調整數組順序使奇數位於偶數前面

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

方法一:數組的引用作爲實參O(N)

class Solution {
public:
    void reOrderArray(vector<int> &array) {    //需要對數組進行修改,故數組引用組爲形參
    vector<int> result;
    int length = array.size();
    
    for (int i = 0; i <length; ++i){
        if (array[i] & 0x1 == 1)
            result.push_back(array[i]);
    }
    
    for (int i = 0; i <length; ++i){
        if((array[i] & 0x1) == 0)    //(array[i] & 0x1)此處不加括號則報錯
            result.push_back(array[i]);
    }
        
    array = result;
    }
};

方法二:使用指針作爲形參

class Solution {
public:
    void reOrderArray(int *pData, unsigned int length)
{
    if(pData == nullptr || length == 0)
        return;

    int *pBegin = pData;
    int *pEnd = pData + length - 1;

    while(pBegin < pEnd)
    {
        // 向後移動pBegin,直到它指向偶數
        while(pBegin < pEnd && (*pBegin & 0x1) != 0)
            pBegin ++;

        // 向前移動pEnd,直到它指向奇數
        while(pBegin < pEnd && (*pEnd & 0x1) == 0)
            pEnd --;

        if(pBegin < pEnd)
        {
            int temp = *pBegin;
            *pBegin = *pEnd;
            *pEnd = temp;
        }
    }
}
};

方法三:函數指針實現通用性

我們可以把這個邏輯框架抽象出來, 而把判斷的標準變成 個函數指針, 也就是用一個單獨的函數來判斷數字是不是符合標準。 這樣我們就把整個函數解糊成兩部分:一是判斷數字應該在數組前半部分還是後半部分的標準; 二是拆分數組的操作。

在下面的代碼中,函數Reor由r根據func的標準把數組pData分成兩部 分: 而函數isEven則是一個具體的標準, 即判斷一個數是不是偶數。 有了這兩個函數, 我們就可以很方便地把數組中的所有奇數移到偶數的前面。解耦的好處就是提高了代碼的重用性,爲功能擴展提供了便利。

class Solution{
public:
	void ReorderOddEven_2(int *pData, unsigned int length)
	{
    Reorder(pData, length, isEven);	//isEven函數名稱代表地址
	}
	
	void Reorder(int *pData, unsigned int length, bool (*func)(int))
	{
	    if(pData == nullptr || length == 0)
	        return;
	
	    int *pBegin = pData;
	    int *pEnd = pData + length - 1;
	
	    while(pBegin < pEnd) 
	    {
	        // 向後移動pBegin
	        while(pBegin < pEnd && !func(*pBegin))
	            pBegin ++;
	
	        // 向前移動pEnd
	        while(pBegin < pEnd && func(*pEnd))
	            pEnd --;
	
	        if(pBegin < pEnd)
	        {
	            int temp = *pBegin;
	            *pBegin = *pEnd;
	            *pEnd = temp;
	        }
	    }
	}
	
	bool isEven(int n)
	{
	    return (n & 1) == 0;
	}

};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章