(劍指Offer)面試題14:調整數組順序使奇數位於偶數前面


題目:

輸入一個整數數組,實現一個函數來調整該數組中數字的順序,使得所有的奇數位於數組的前半部分,所有的偶數位於位於數組的后半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。

如果去掉約束條件:並保證奇數和奇數,偶數和偶數之間的相對位置不變?

思路:

如果要保證奇數和奇數,偶數和偶數之間的相對位置不變,那么需要開辟新的空間來保存奇數和偶數,方法有兩種:

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];
	}
};

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM