LeetCode 283.移动零:一个非常有用的技巧

题目描述:

  给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

示例:

输入: [0,1,0,3,12]
输出: [1,3,12,0,0]

要求:

必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。

解题核心思想

  移动零是一个很有用的技巧。接下来,讲下这个技巧的实现原理。
  这里参考了快速排序的思想,快速排序首先要确定一个待分割的元素做中间点 x,然后把所有小于等于 x 的元素放到 x 的左边,大于 x 的元素放到其右边。
  这里我们可以用0当做这个中间点,把不等于0(注意题目没说不能有负数)的放到中间点的左边,等于0的放到其右边。这的中间点就是0本身,所以实现起来比快速排序简单很多,我们使用两个指针 和 j,只要 nums[i]!=0,我们就交换 nums[i] 和 nums[j]
可以看下下面的gif图:

图片

代码:

 func moveZeroes(_ nums: inout [Int]) {
        if nums.count == 0 { return }
        var j = 0
        for i in 0..<nums.count {
            if nums[i] != 0 {
                let temp = nums[i]
                nums[i] = nums[j]
                nums[j] = temp
                j += 1
            }
        }
    }

详细的讲解:

  为了更加清楚的表达这道题的解题过程,我结合解题思想和代码,带大家一起来详细的将步骤表达出来。
  首先,代码中的 对应 gif 图中的 bnums[i] 对应 gif 图中 ;我们以 nums = [0,1,0,3,12]为例,下面是详细的步骤:

  1. i = 0,nums[i] = 0, for循环继续

  2. i = 1,nums[i] = 1,此时j = 0,nums[i]和nums[j]交换nums变成了 [1,0,0,3,12],j += 1,继续for循环

  3. i = 2,nums[i] = 0,for循环继续

  4. i = 3,nums[i] = 3,此时j = 1,nums[i]和nums[j]交换nums变成了 [1,3,0,0,12],j += 1,继续for循环

  5. i = 4,nums[i] = 12,此时j = 2,nums[i]和nums[j]交换nums变成了 [1,3,12,0,0],j += 1,继续for循环

  6. 结束

  通过这个例子的详细步骤,我们就可以很快的理解移动0这个算法思想是什么了。为什么说这个移动0的思想很有用了,你们看下面这个题,

给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

示例:

输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]

   这个题,看起来很麻烦,但是其本质就是【移动0】。解题代码如下:
  思想:移动2、和移动1,就是把全是2的移动到最后,再把全是1的移动到最后,得到就是结果啦。

 func sortColors(_ nums: inout [Int]) {
        if nums.count == 0 { return }
        var blue = 0
        var white = 0
        for i in 0..<nums.count {
            if nums[i] != 2 {
                let temp = nums[blue]
                nums[blue] = nums[i]
                blue += 1
                nums[i] = temp
            }
        }

        for i in 0..<blue {
            if nums[i] != 1 {
                let temp = nums[white]
                nums[white] = nums[i]
                white += 1
                nums[i] = temp
            }
        }
    }

总结:

今天主要讲解了移动0这道题的解法,讲这道题的原因是,因为这道题不仅是一道题目,更是一种解题技巧和思想。大家一定要掌握哦。希望帮助到大家。

欢迎关注【无量测试之道】公众号,回复【领取资源】
Python编程学习资源干货、
Python+Appium框架APP的UI自动化、
Python+Selenium框架Web的UI自动化、
Python+Unittest框架API自动化、
资源和代码 免费送啦~
文章下方有公众号二维码,可直接微信扫一扫关注即可。

备注:我的个人公众号已正式开通,致力于测试技术的分享,包含:大数据测试、功能测试,测试开发,API接口自动化、测试运维、UI自动化测试等,微信搜索公众号:“无量测试之道”,或扫描下方二维码:

在这里插入图片描述
添加关注,让我们一起共同成长! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wu_Candy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值