題目:
輸入一個整數數組,實現一個函數來調整該數組中數字的順序,使得所有的奇數位於數組的前半部分,所有的偶數位於位於數組的后半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。
如果去掉約束條件:並保證奇數和奇數,偶數和偶數之間的相對位置不變?
思路:
如果要保證奇數和奇數,偶數和偶數之間的相對位置不變,那么需要開辟新的空間來保存奇數和偶數,方法有兩種:
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];
}
};
