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

在这里插入图片描述
不难,难的是要写出最完美的方法,这里用了三种,如果实在不行第一种总写得出的
第一种:时复O(n),空复O(n),开辟一个额外数组用于辅助,遍历两次碰到奇数就直接push_back进去,第二次碰到偶数就push_back进去。或者碰到奇数直接放进去,然后从后往前,碰到偶数就从后往前放。
第二种:O(n^2)和O(1),冒泡排序,从前往后找到奇数就在循环内部往前遍历,如果遍历到奇数就直接break,因为按理说前面的奇数已经被处理完了,前面奇数的前面是不会有偶数的。如果遍历到偶数,就慢慢swap过去,将当前位j和j+1也就是奇数那一位交换。
第三种:O(n^2)和O(1),插排。k记录排好的奇数个数。好像其实和法2一样的,只不过它是检测是否是奇数,我们是从j遍历到k+1,一路交换过去就行了。

class Solution {
public:
    void reOrderArray(vector<int> &array) {
        //1第一种方法两种实现,第一次循环找奇数,第二次循环找偶数,全部push_back也行,像这样做也行
        /*vector<int> res(array.size());
        int left = 0, right = array.size() - 1;
        for(int i = 0; i < array.size(); ++i){
            if(array[i] % 2 == 1){
                res[left++] = array[i]; 
            }
        }
        for(int i = array.size() - 1; i >= 0; --i){
            if(array[i] % 2 == 0){
                res[right--] = array[i];
            }
            if(right < left) break;
        }
        for(int i = 0; i < array.size(); ++i){
            array[i] = res[i];
        }*/
        
        /*2这题想拿offer必须原地排序,来一个冒泡的
        从前往后遍历,遍历到第一个奇数时,找到奇数就退出,因为此奇数前面一定没有偶数了
        找到偶数就逐个往前交换
        for(int i = 0; i < array.size(); ++i){
            if(array[i] % 2 == 1){
                for(int j = i - 1; j >= 0; --j){
                    if(array[j] % 2 == 1) break;
                    swap(array[j+1],array[j]);
                }
            }
        }*/
        
        /*插入法,插完之后记得所有数“后移一位”,插入法的相对位置不变,稳定性
        当前位是偶数,就继续往后找到第一个奇数,将这个奇数插到找到偶数前*/
        int m = array.size();
        int k = 0;//记录已经摆好位置的奇数的个数
        for(int i = 0; i < m; i++){
            if(array[i] % 2 == 1){//如果是奇数
                int j = i;
                while(j > k){//j >= k+1,一个一个往前换,顺便后移数组
                    int tmp = array[j];
                    array[j] = array[j-1];
                    array[j-1] = tmp;
                    j--;
                }
                k++;
            }
        }
    }
};

用bubblesort,记得用一个bool值判断这一轮是否有交换,如果没有就可以直接退出了

vector<int> reOrderArray(vector<int>& array) {
        // write code here
        //要保证奇数和奇数相对位置不变,偶数和偶数相对位置不变,那就不可以随便交换了
        //还是得用冒泡排序,内部从左往右交换,只和自己相邻一个交换,这样就不会出现1,4,6,5这样的情况交换后是
        //1,5,6,4的情况了,我们只会让4和6换,换不了就是6和5,到下一轮就是4和5,
        //总的来说就是一轮把最右边的偶数放到结尾处
        bool isSorted = true;
        for(int i = array.size()-1; i > 0 && isSorted; ++i){
            isSorted = false;
            for(int j = 0; j < i-1; ++j){
                if(array[j] % 2 == 1) continue;
                else if(array[j+1]%2 == 1){
                    isSorted = true;
                    swap(array[j],array[j+1]);
                }
            }
        }
        return array;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值