调整数组顺序使奇数位于偶数前面

面试题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;
	}

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