剑指offer13__调整数组顺序使奇数位于偶数前面_题解

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

题目描述

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。

分析

方案一:辅助数组

/**
时间复杂度:O(n)
空间复杂度:O(n)
**/
class Solution {
public:
    void reOrderArray(vector<int> &array) {
        vector<int> odd, even;
        for(int x : array){
            if(x & 1){
                odd.push_back(x);//odd奇数
            }else{
                even.push_back(x);//even偶数
            }
        }
        int i = 0;
        //array.size() = odd.size() + even.size()
        //将odd[0,odd.size()-1]中的奇数复制到array[0,odd.size()-1]
        for(i = 0; i < odd.size(); i++){
            array[i] = odd[i];
        }
        //将even[0,even.size()-1]中的偶数复制到array[odd.size(),array.size()-1]
        for(int j = 0; j < even.size(); j++){
            array[i + j] = even[j];//注意array的下标从odd.size()开始,故需要加上i
        }
    }
};

方案二:in-place就地算法

设置变量 \(i\) 表示奇数放好的下一个位置,初始 \(i=0\) 表示还没有一个奇数放好

设置变量 \(j\) 表示数组的下标,初始 \(j=0\) 表示从下标0开始遍历

①如果遇到偶数,\(j++\)

②如果遇到奇数,先将 \([i, j - 1]\)的数据整体向右移动 \(1\)位,将奇数插入到 \(i\) 号位置,然后 \(i\) 往后移动一个位置

③整个数组遍历完毕,结束

/**
时间复杂度:O(n^2)
空间复杂度:O(1)
**/
class Solution {
public:
    // in-place算法
    void reOrderArray(vector<int> &array)
    {
        int i = 0;//i表示奇数放好的下一个位置
        for (int j = 0; j < array.size(); j++)
        {
            //如果遇到奇数
            if (array[j] & 1)
            {
                int tmp = array[j];
                //将[i,j-1]的数据整体向右移动1位
                for (int k = j - 1; k >= i; k--)
                {
                    array[k + 1] = array[k];
                }
                //将奇数插入到array[i],i向后移动1个位置
                array[i++] = tmp;
            }
        }
    }
};

方案三:STL库函数 \(stable\_partition()\)

\(stable\_partition()\) 函数定义在<algorithm>头文件中,其语法格式如下:

BidirectionalIterator stable_partition 
(BidirectionalIterator first, 
 BidirectionalIterator last,
 UnaryPredicate pred);

其中,first 和 last 都为双向迭代器,其组合 [first, last) 用于指定该函数的作用范围;pred 用于指定筛选规则。同时,stable_partition() 函数还会返回一个双向迭代器,其指向的是两部分数据的分界位置,更确切地说,指向的是第二组数据中的第 1 个元素。

/**
时间复杂度:O(n)
空间复杂度:O(n)
**/
class Solution {
public:
    void reOrderArray(vector<int> &array) {
        stable_partition(array.begin(), array.end(), [](int x) {return x&1;} );
    }
};
posted @ 2020-12-11 21:54  RiverCold  阅读(25)  评论(0编辑  收藏  举报