【剑指offer-C++】JZ21: 调整数组顺序使奇数位于偶数前面(一)

【剑指offer-C++】JZ21: 调整数组顺序使奇数位于偶数前面

    • 题目描述
    • 解题思路

题目描述

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

数据范围:0≤n≤5000,数组中每个数的值 0≤val≤10000。
要求:时间复杂度 O(n),空间复杂度 O(n)。
进阶:时间复杂度 O(n2 ),空间复杂度 O(1)。

输入:[1,2,3,4]
返回值:[1,3,2,4]
输入:[2,4,6,5,7]
返回值:[5,7,2,4,6]
输入:[1,3,5,6,7]
返回值:[1,3,5,7,6]

解题思路

调整数组顺序使奇数位于偶数前面(一):最直观的想法是,如果是仅仅调整数组顺序使奇数位于偶数前面,那么就使用双指针,一个指针从前往后遍历寻找数组中的偶数,一个指针从后往前遍历寻找数组中的奇数,然后交换两者,但是题目中要求保证奇数和奇数、偶数和偶数之间的相对位置不变,那么双指针的想法就有点不可行了,于是就想到从前往后遍历数组,奇数就存在odd数组中,偶数就存在even数组中,然后再将even数组追加到odd数组后面,并返回odd数组即可。

vector<int> reOrderArray(vector<int>& array) {
        vector<int> odd;
        vector<int> even;
        for(int i=0;i<array.size();i++)
        {
            if(array[i]%2!=0)
                odd.push_back(array[i]);
            else
                even.push_back(array[i]);
        }
        for(int j=0;j<even.size();j++)
        {
            odd.push_back(even[j]);
        }
        return odd;
    }

优化:那到底能不能不使用额外空间而直接在原数组上修改呢?使用变量i表示奇数放好的下一个位置,最开始i=0表示没有一个奇数,j表示数组的下标,对数组进行遍历。具体做法是,如果遇到偶数则j++,如果遇到奇数则将[i,j-1]的数组整体后移一位接着将j位置的奇数插入到i的位置然后将i后移一位,直到整个数组遍历结束。

vector<int> reOrderArray(vector<int>& array) 
{
    int i=0;
    for(int j=0;j<array.size();j++)
    {
        if(array[j]%2==1) //遇到奇数
        {
            int temp=array[j];
            //将[i,j-1]数组后移
            for(int k=j-1;k>=i;k--)
            {
                array[k+1]=array[k];
            }
            array[i]=temp;
            //i后移一位
            i++;
         }
    }
    return array;
}

你可能感兴趣的:(剑指offer,c++,算法,数据结构)