力扣刷题——调整数组顺序使奇数位于偶数前面

题目:

第一次做的代码:超出时间限制

class Solution {
public:
    vector<int> exchange(vector<int>& nums) {
        //思路:利用双指针
        //指针i 指向数组的首位, 指针 j 指向数组的末尾
        //指针i的目的是找到偶数,指针j的目的是找到奇数

        int i=0, j=nums.size()-1;

        // i从前往后找,j从后往前找
        //当i>=j时,便完成 数组前面是奇数, 后面是奇数

        while(i!=j){
            
            // 如果i找到的是偶数,且j找到的是奇数,交换它们的值
            if(nums[i]%2==0 && nums[i]%2 !=0){
                swap(nums[i],nums[j]);
            }

            // i要找的是偶数,找不到i往后移动,最终要实现i的左边全是奇数
            if(nums[i]%2!=0){
                ++i;
            }

            //如果j找到的是偶数,j往前移动,最终要实现j的右边边全是奇数
            if(nums[j]%2==0){
                --j;
            }
        }

        return nums;

    }
};

反思:思路不对,考虑不周
正确的思路应该是:

  1. 指针 i 要找数组中的偶数,直到找到为止;同样,指针 j 要找数组中的奇数,直到找到为止
  2. 第一步的目的是一定让 i 找到偶数, j 找到奇数, 方便后序的交换
  3. 交换找到的两个数

此外,在第一步的时候,有个特殊情况我未考虑到,举个栗子:数组里元素是 1,2,4,6,8
i 找到偶数,指向数字2; j 找到奇数,指向数字1;如果不加限制条件,那么这两个数交换之后 就显得很不合理。

😔可见我的代码漏洞百出 。。。稀碎(ง •_•)ง)

所以呢,应该在第一步 i 和 j 找数的时候,加上限制条件满足 i < j 则执行,等 i 找到了偶数, j 找到了奇数,那么就可以交换了

看过题解之后,在判断所找的数是奇数还是偶数时,可以用位运算(为什么呢?位运算比较快——我的理解)
奇数 和 1 按位与 == 1;偶数 和 1 按位与 ==0

因此,最终的代码:

class Solution {
public:
    vector<int> exchange(vector<int>& nums) {
        //思路:利用双指针
        //指针i 指向数组的首位, 指针 j 指向数组的末尾
        //指针i的目的是找到偶数,指针j的目的是找到奇数

        int i=0, j=nums.size()-1;

        // i从前往后找,j从后往前找
        //当i>=j时,便完成 数组前面是奇数, 后面是奇数

        while(i<j){
            
            //奇数 和 1 按位与得 1, 偶数 和 1 按位与得 0
            // i 直到 找到偶数为止, ==的优先级要高于&, 要加()
            while(i<j && (nums[i]&1)==1){
                i++;
            }

            // j 直到 找到奇数为止
            while(i<j && (nums[j]&1)==0){
                j--;
            }

            //好了, i找到了偶数, j找到了奇数,那么达成协议,交易成功【手动滑稽】
            swap(nums[i], nums[j]);
        }

        return nums;

    }
};

过几天我还要再做一遍,今天是看了题解,再过几天能不能自己写出来就不一定了U•ェ•*U

继续刷ing (。・∀・)ノ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值