描述
输入一个长度为 n 整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前面部分,所有的偶数位于数组的后面部分
输入:[1,2,3,4,5,6,7,8]
输出:[1,7,3,5,4,6,2,8]
思路:利用对撞指针,一个指向头部,一个指向尾部,如果头部遇到偶数,那么停下;如果尾部遇到奇数,那么停下,此时交换两个指针指向的元素即可
void DO(vector<int> &vec)
{
int n = vec.size();
int begin = 0,end=n-1;
while(begin<end)
{
while(begin<end && vec[begin]%2!=0) begin++;
while(begin<end && vec[end]%2==0) end--;
swap(vec[begin],vec[end]);
}
}
那么题目再次要求保证奇数和奇数,偶数和偶数之间的相对位置不变。
输入:[1,2,3,4,5,6,7,8]
输出:[1,3,5,7,2,4,6,8]
方法一:较为好想的方法:开辟一个和原数组一样的空间大小,然后计算原数组中偶数有多少个,在对原数组依次遍历时,我们知道奇数起始地址=0,那么偶数的起始地址=n-count(偶数个数)
vector<int> reOrderArray(vector<int>& array) {
// write code here
//准备一个和array相同的数组,然后遍历array,奇数放在数组头部,偶数放在数组尾部
int n = array.size(),count=0;
//计算数组中偶数出现次数
for(int i=0;i<n;++i)
if(array[i]%2==0)
count++;
vector<int> vec(n,0);
int begin=0,end = n-count;
for(int i=0;i<n;++i)
{
if(array[i]%2==1)
vec[begin++] = array[i];
else
vec[end++] = array[i];
}
return vec;
}
方法二:类似于插入排序,一个指针指向偶数的下标,一个指向奇数的下标,如果遇到奇数,那么偶数指针向后移动,直到空出一个位置给当前奇数,然后偶数指针+1;
vector<int> reOrderArray(vector<int>& array) {
int n = array.size(),count=0;
//j存储的是上一个偶数的下标,当出现一个奇数时,先保存该奇数,然后对上一个偶数坐标向后移动,最终将该奇数放在空出的位置
int j=0;//保存上一个偶数的下标
int temp=0;
for(int i=0;i<n;++i)
{
temp = array[i];
if(temp%2==0)
continue;
else
{
int k=i;
//偶数向后移动,插入奇数
while(k>j)
{
array[k] = array[k-1];
k--;
}
array[k] = temp;
//偶数指针向后移动一位
j++;
}
}
return array;
}