题目描述
描述:输入一个长度为 n 整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前面部分,所有的偶数位于数组的后面部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
数据范围:0≤n≤5000,数组中每个数的值 0≤val≤10000。
要求:时间复杂度 O(n),空间复杂度 O(n)。
进阶:时间复杂度 O(n2 ),空间复杂度 O(1)。
输入:[1,2,3,4]
返回值:[1,3,2,4]
输入:[2,4,6,5,7]
返回值:[5,7,2,4,6]
输入:[1,3,5,6,7]
返回值:[1,3,5,7,6]
解题思路
调整数组顺序使奇数位于偶数前面(一):最直观的想法是,如果是仅仅调整数组顺序使奇数位于偶数前面,那么就使用双指针,一个指针从前往后遍历寻找数组中的偶数,一个指针从后往前遍历寻找数组中的奇数,然后交换两者,但是题目中要求保证奇数和奇数、偶数和偶数之间的相对位置不变,那么双指针的想法就有点不可行了,于是就想到从前往后遍历数组,奇数就存在odd数组中,偶数就存在even数组中,然后再将even数组追加到odd数组后面,并返回odd数组即可。
vector<int> reOrderArray(vector<int>& array) {
vector<int> odd;
vector<int> even;
for(int i=0;i<array.size();i++)
{
if(array[i]%2!=0)
odd.push_back(array[i]);
else
even.push_back(array[i]);
}
for(int j=0;j<even.size();j++)
{
odd.push_back(even[j]);
}
return odd;
}
优化:那到底能不能不使用额外空间而直接在原数组上修改呢?使用变量i表示奇数放好的下一个位置,最开始i=0表示没有一个奇数,j表示数组的下标,对数组进行遍历。具体做法是,如果遇到偶数则j++,如果遇到奇数则将[i,j-1]的数组整体后移一位接着将j位置的奇数插入到i的位置然后将i后移一位,直到整个数组遍历结束。
vector<int> reOrderArray(vector<int>& array)
{
int i=0;
for(int j=0;j<array.size();j++)
{
if(array[j]%2==1) //遇到奇数
{
int temp=array[j];
//将[i,j-1]数组后移
for(int k=j-1;k>=i;k--)
{
array[k+1]=array[k];
}
array[i]=temp;
//i后移一位
i++;
}
}
return array;
}