题目:给定一个存放整数的数组,重新排列数组使得数组左边为奇数,右边为偶数。
要求:空间复杂度O(1),时间复杂度为O(n)。
分析:分别从数组两端向中间推进。推出条件为左右相撞
当左端值为偶数,并且右端值为奇数时交换二值,用到一个临时空间。
当左端值为奇数,向右推进一个单位
当右端值为偶数,向左推进一个单位
我最开始写的代码:
void order(int* arr,int n) { int i=0,j=n-1; while(i<=j) // =可去掉,只剩一个元素就不用操作了。改成i<j { bool iEven=(arr[i]%2==0); bool jEven=(arr[j]%2==0); if(iEven && jEven) { j++; } else if(iEven && !jEven) { swap(arr[i],arr[j]); i++; j--; } else if(!iEven && jEven) { i++; j--; } else if(!iEven && !jEven) { i++; } } }
上面的代码虽然正确,但总感觉有点啰嗦,网上面看的答案有点比较简洁:
#include<iostream> using namespace std; #define odd(s) (s%2)?1:0 //奇数 #define even(s) (s%2)?0:1 //偶数 void order2(int* arr,int n) { int i=0,j=n-1; bool iEven,jEven; while(i<j) { if( even(arr[i]) && odd(arr[j])) { int tmp=arr[i];arr[i]=arr[j];arr[j]=tmp; } if(odd(arr[i])) { i++; } if(even(arr[j])) { j--; } } } int main() { int arr[] = {1,2,3,4,5}; int length = sizeof(arr)/sizeof(arr[0]); order(arr,length); for(int i=0;i<length;i++) cout<<arr[i]<<ends; cout<<endl; }
输出:1 5 3 4 2