您的位置:首页 > 职场人生

面试题14:调整数组顺序使奇数在偶数前面

2016-06-04 10:28 393 查看
      题目:输入一个整数数组,实现一个函数来调整数组中数字的顺序,使得奇数位于数组的前半部分,偶数位于数组的后半部分。

     咋一看,没有限定空间复杂度,直接想到声明两个数组,一个存奇数,一个存偶数。再合并。时间复杂度O(n),空间复杂度O(n),代码如下:

      

class Solution {
public:
void reOrderArray(vector<int> &array) {
vector<int> oddArray;
vector<int> evenArray;
int i;
for(i=0;i<array.size();i++)
{
if(array[i]%2==1)
{
oddArray.push_back(array[i]);
}
else
evenArray.push_back(array[i]);
}
for(i=0;i<oddArray.size();i++)
{
array[i]=oddArray[i];
}
for(i=0;i<evenArray.size();i++)
{
array[oddArray.size()+i]=evenArray[i];
}
return ;
}
};
     面试时感觉这种肯定过不了。考虑下节省空间复杂度。

     再看一下题目,发现我一开始就跑偏了,我开始想的是数组以前元素的相对顺序不变,结果看本题好像没有这个意思,那就更简单了。

     采用两个指针,一个指向数组的开头,一个指向数组的结尾。当开头的指针遇到奇数,跳过,遇到偶数,停止,指向数组末尾的指针遇到偶数,跳过,遇到奇数,停止。然后两个指针交换元素。这种思想类似于快速排序中的partition思想。算法原地调整,时间复杂度O(n),空间复杂度O(1).

     先试着写个。

     

class Solution {
public:
void reOrderArray(vector<int> &array) {
int i=0,j=array.size()-1;
while(i<=j)
{
while(i<array.size()&&array[i]%2==1) i++;
while(j>=0&&array[j]%2==0) j--;
if(i<=j)
swap(array[i],array[j]);
}
return;
}
};
      不过快速排序本身就是不稳定的排序方法,这种方法虽然奇数在前,偶数在后,但是肯定数组的元素相对顺序和以前不同。如1,2,3,4,5肯定变成了1,5,3,4,2.

      看网上有人为了使算法具有稳定性,采用归并排序,可是归并排序要的空间复杂度就是O(n),有那个O(n)还不如直接像开始一样声明两个数组呢。

      想到腾讯今年的实习笔试,有一道类似的题目,但是是要求空间复杂度是O(1),那没办法,只有牺牲时间复杂度了。

      代码如下:

       

class Solution {
public:
    void reOrderArray(vector<int> &array) {
        int len=array.size(),i,j,k,l;
        for(i=len-1,j=len-1;i>=0&&j>=0;)          //i,j分别代表最前的一个偶数,奇数指针
        {
            if(array[i]%2==0)                     //当前为偶数,直接跳过
            {    
                i--;
                j--;
            }
            else
            {
                for(k=j-1;k>=0;)                 //当前array[i]是奇数,寻找下一个偶数,再将偶数和后面所有的不是偶数的都交换
                {
                    if(array[k]%2==1)
                        k--;
                    else
                    {
                        int temp=array[k];
                        memcpy((char *)(&array[k]),(char *)(&array[k+1]),sizeof(int)*(i-k));
                        array[i]=temp;
                        break;
                       /* for(l=k;l<i;l++)
                        {
                            swap(array[l],array[l+1]);
                        }
                        break;*/
                    }
                }
                i=i-1;                              //更新偶数指针
                j=k;                                //更新奇数指针
            }
        }
    }
};
     本算法理论上时间复杂度O(n*n*n),但是实际肯定不到。思考用内存拷贝,会快点,理论时间复杂度为O(n*n).
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: