題目:
輸入一個整數數組,實現一個函數來調整該數組中數字的順序,使得所有的奇數位於數組的前半部分,所有的偶數位於位於數組的后半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。
如果去掉約束條件:並保證奇數和奇數,偶數和偶數之間的相對位置不變?
思路:
如果要保證奇數和奇數,偶數和偶數之間的相對位置不變,那么需要開辟新的空間來保存奇數和偶數,方法有兩種:
1、開辟一個新數組,遍歷第一遍原數組,將奇數依次寫入新數組,遍歷第二遍原數組,將偶數依次寫入新數組,返回新數組;
2、開辟兩個數組,遍歷一遍原數組,分別將奇數和偶數存入兩個新數組,再將奇數數組和偶數數組分別寫入原數組,返回原數組;
如果無需保證奇數和奇數,偶數和偶數之間的相對位置不變,那么可以通過前后遍歷,奇偶對換的方法來實現:
維護兩個指針,分別指向數組的首尾,然后一個向后一個向前,在兩個指針相遇之前,如果第一個指針指向偶數,而第二個指針指向奇數,那么就交換這兩個數。(無需開辟新空間)
類似題目:
- 將題目改成將數組分成兩部分,所有負數在非負數前面;
- 將題目改成將數組分成兩部分,能被3整除的在不能被3整除的前面;
為了讓代碼的擴展性更強,可以將這些判斷條件單獨寫成一個函數接口,而主代碼框架保持不變。
代碼:
#include <iostream> #include <vector> using namespace std; // not changed the relative position void ReOrderOddEven_1(vector<int> &array){ if(array.size()<=0) return; vector<int> odds; vector<int> evens; unsigned int i; for(i=0;i<array.size();i++){ if((array[i]&0x1)!=0) odds.push_back(array[i]); else evens.push_back(array[i]); } for(i=0;i<odds.size();i++) array[i]=odds[i]; int k=i; for(i=0;i<evens.size();i++) array[k++]=evens[i]; } // changed the relative position void ReOrderOddEven_2(int *pdata,unsigned int length){ if(pdata==NULL || length<=0) return; int *pBegin=pdata; int *pEnd=pdata+length-1; while(pBegin<pEnd){ while(pBegin<pEnd && (*pBegin&0x1)!=0) pBegin++; while(pBegin<pEnd && (*pEnd&0x1)==0) pEnd--; if(pBegin<pEnd){ int tmp=*pBegin; *pBegin=*pEnd; *pEnd=tmp; } } } bool isEven(int n){ return (n&1)==0; } // more expansible void ReOrderOddEven_3(int *pdata,unsigned int length,bool (*func)(int)){ if(pdata==NULL || length<=0) return; int *pBegin=pdata; int *pEnd=pdata+length-1; while(pBegin<pEnd){ while(pBegin<pEnd && !func(*pBegin)) pBegin++; while(pBegin<pEnd && func(*pEnd)) pEnd--; if(pBegin<pEnd){ int tmp=*pBegin; *pBegin=*pEnd; *pEnd=tmp; } } } int main() { int A[]={1,2,3,4,5,6,7,8,9}; int length=sizeof(A)/sizeof(A[0]); ReOrderOddEven_2(A,length); for(int i=0;i<length;i++) cout<<A[i]<<" "; cout<<endl; int B[]={1,2,3,4,5,6,7,8,9}; vector<int> C(B,B+length); ReOrderOddEven_1(C); for(int i=0;i<length;i++) cout<<C[i]<<" "; cout<<endl; ReOrderOddEven_3(B,length,isEven); for(int i=0;i<length;i++) cout<<B[i]<<" "; cout<<endl; return 0; }
在線測試OJ:
http://www.nowcoder.com/books/coding-interviews/beb5aa231adc45b2a5dcc5b62c93f593?rp=1
AC代碼:
class Solution { public: void reOrderArray(vector<int> &array) { if(array.size()<=0) return; vector<int> odds,evens; unsigned int i; for(i=0;i<array.size();i++){ if((array[i]&0x1)!=0) odds.push_back(array[i]); if((array[i]&0x1)==0) evens.push_back(array[i]); } for(i=0;i<odds.size();i++) array[i]=odds[i]; int k=i; for(i=0;i<evens.size();i++) array[k++]=evens[i]; } };