LeetCode 283. 移动零

283. 移动零 - 力扣(LeetCode) (leetcode-cn.com)

目录

方案1:冒泡(巨慢)

运行结果

 代码

方案2:化用快速排序的手段

运行结果

 代码

最佳方案:方案2改进版

代码

运行结果


方案1:冒泡(巨慢)

运行结果

LeetCode 283. 移动零_第1张图片

 代码

class Solution {
public:
    void moveZeroes(vector& nums) {
        int beg = 0, N = nums.size();
        while (beg != N && nums[beg]) ++beg;
        if (beg == N) return;

        for (int count = 1; count != N; ++count) {
            bool no_op = true;
            for (int bubble = beg; bubble != N - count; ++bubble) {
                if (!nums[bubble] && nums[bubble + 1]) {
                    swap(nums[bubble], nums[bubble + 1]);
                    no_op = false;
                }
            }
            if (no_op) return;
        }
    }
};

方案2:化用快速排序的手段

运行结果

LeetCode 283. 移动零_第2张图片

 代码

class Solution {
public:
    void moveZeroes(vector& nums) {
        int i = -1, j = -1, N = nums.size();
        while(++j != N) if(nums[j]) swap(nums[++i], nums[j]);
    }
};

最佳方案:方案2改进版

不难发现方案2其实是有多余的操作的。我们知道当 j 到达数组尾部、循环结束的时候,从i + 1到 j 位置的元素应该全部为0,我们只需要最终保证其如此,至于中间过程中i + 1~ j 之间是否全部为0无关紧要。因此当 j 定位到一个非0元素之后根本不需要和i + 1位置的元素相交换,只需要把它放到i + 1位置上即可,当 j 到达数组尾部之后,再把i + 1到 j 位置上的元素全部置0也不迟。这样就不需要交换操作,只需要一步赋值操作就行了,提高了代码效率。

代码

class Solution {
public:
    void moveZeroes(vector& nums) {
        int i = -1, j = -1, N = nums.size();
        while(++j != N) if(nums[j]) nums[++i] = nums[j];
        while(++i != N) nums[i] = 0;
    }
};

运行结果

LeetCode 283. 移动零_第3张图片

 

你可能感兴趣的:(leetcode,算法,c++,数据结构,排序算法)