剑指offer系列——13.调整数组顺序使奇数位于偶数前面

Q:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
C:时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
A:
1.最简单的,开辟新的数组

    void reOrderArray(vector<int> &array) {
        vector<int> even;
        vector<int> odd;
        int length = array.size();
        for (int i = 0; i < length; i++) {
            if (array[i] % 2 == 1) {
                odd.push_back(array[i]);
            }else{
                even.push_back(array[i]);
            }
        }
        odd.insert(odd.end(),even.begin(),even.end());//复习一下insert用法
        array = odd;
    }

2.偶数删除后尾插

    void reOrderArray(vector<int> &array) {
        vector<int>::iterator even = array.begin();
        int length = array.size();
        for (int i = 0; i < length; i++) {
            if (*even % 2 == 0) {
                int temp = *even;
                even = array.erase(even);
                array.push_back(temp);
            } else
                even++;
        }
    }

3.排序:注意,常用内部排序中稳定的排序算法有插入排序,冒泡排序和归并排序三种,使用其他的排序方法为不稳定排序,不满足条件。
3.1插入排序

    void reOrderArray4(vector<int> &array) {
        for (int i = 1; i < array.size(); i++) {
            int tmp = array[i];
            if (tmp % 2 == 1) {
                for (int j = i; j > 0; j--) {
                    if (array[j - 1] % 2 == 0) {
                        int t = array[j];
                        array[j] = array[j - 1];
                        array[j - 1] = t;
                    }
                }
            }
        }
    }

3.2冒泡排序

    void reOrderArray(vector<int> &array) {
        for (int i = 0; i < array.size(); i++) {
            for (int j = array.size() - 1; j > i; j--) {
                if (array[j] % 2 == 1 && array[j - 1] % 2 == 0) //前偶后奇交换
                    swap(array[j], array[j - 1]);
            }
        }
    }

3.3归并排序

//没有自己写,借用讨论区的java代码,感谢@worsun
public class Solution {
    public void reOrderArray(int [] array) {
        //用归并排序的思想
        int length = array.length;
        if(length == 0){
            return;
        }
        int[] des = new int[length];
        MergeMethod(array, des, 0,length - 1);
    }
    public void MergeMethod(int[] array, int [] des, int start, int end){
        if(start < end){
            int mid = (start + end) / 2;
            MergeMethod(array, des, start, mid);
            MergeMethod(array, des, mid + 1, end);
            Merge(array, des, start, mid, end);
        }
    }
   
    public void Merge(int[] array, int[] des, int start, int mid, int end){
        int i = start;
        int j = mid + 1;
        int k = start;
        while(i <= mid && array[i] % 2 == 1){
            des[k++] = array[i++];
        }
        while(j <= end && array[j] % 2 == 1){
            des[k++] = array[j++];
        }
        while(i <= mid){
            des[k++] = array[i++];
        }
        while(j <= end){
            des[k++] = array[j++];
        }
       
        for(int m = start; m <= end; m++){
            array[m] = des[m];
        }
    }
}

4.STL stable_partition函数 或 stable_sort函数

bool isOk(int n){  return ((n & 1) == 1); //奇数返回真 }
class Solution{
    void reOrderArray(vector<int> &array){
        stable_partition(array.begin(),array.end(),isOk);
    }
};

//bool函数写在类里面需要加static,详见P.S.
static bool comp(const int &a,const int &b){
        return a%2==1&&b%2==0;
    }
void reOrderArray(vector<int> &array) {
        stable_sort(array.begin(),array.end(),comp);
    }

P.S.非静态成员函数会传入一个隐参数this指针,在调用函数指针的时候和普通的函数就会不同。
解决办法:
(1)改用static成员函数,没有this指针
(2)把compare函数放在类外面
5.因为是数组,如果不让有额外的空间,可以碰到一个奇数,和前面的每个偶数换位置

原文地址:https://www.cnblogs.com/xym4869/p/12249170.html