一、开辟新数组法
1.分析:用快慢指针遍历数组,慢指针指向最后一个已调整位置奇数,快指针向后遍历,开辟一个新数组保存遍历过程中的偶数,遇到奇数则将其移动到慢指针的下一个位置。
2.代码
void reOrderArray_1(vector<int> &array) { vector<int> temp_even; int slow,fast,size=array.size(); for (slow=-1,fast=0; fast<size; ++fast){ if (array[fast] & 0x1) //若fast指向奇数,将其移动到指定位置 array[++slow] = array[fast]; else temp_even.push_back(array[fast]); } for (fast=0; fast<temp_even.size(); ++fast) array[++slow] = temp_even[fast]; }
3.复杂度
时间复杂度:O(n)
空间复杂度:O(n)
二、不开辟新数组:
1.分析:
- 用两个下标i,j进行遍历;
- 当i走到偶数时停下,并让j从i的后一个元素开始遍历;(若i走到队尾则循环结束)
- 若j所指的是偶数则继续前进,j遇到奇数则停下(如果j都没遇到奇数则在队尾停下,结束。)。
- 此时j所指的是奇数,i所指的是偶数(i到j-1都是偶数)。
- 则可以用临时变量temp保存j对应的值,然后从j-1开始到i,挨个后移一位。
- 将temp保存的值插入到i的位置。
优化:冒泡排序也可以保证相对位置不变,所以用冒泡排序写起来会更方便。
2.代码
void reOrderArray_2(vector<int> &array) { int len = array.size(); if(len <= 1){ // 数组空或长度为1 return; } int i = 0; while(i < len){ int j = i + 1; if(array[i]%2 == 0){ // a[i]为偶数,j前进,直到替换 while(array[j]%2 == 0){ // j为偶数,前进 if(j==len-1)// i为偶数,j也为偶数,一直后移到了末尾,证明后面都是偶数 return; j++; } // 此时j为奇数 int count = j-i; int temp = array[i]; array[i] = array[j]; while(count>1){ array[i+count] = array[i+count-1];//数组后移 count--; } array[i+1] = temp; } i++; } }
3.复杂度
时间复杂度:O(n2)
空间复杂度:O(1)