LeetCode刷题Python Day3 Q283移动零

此专栏所有文章仅用于自我学习记录。

题目:

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

示例:

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

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/move-zeroes
 

解答:

先是很自然的一个解答。照常理思维,先去把前面非0的部分排序排好,顺便统计0的个数,用到i和j两个变量。第二步,再末尾重写对应个数的0.

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        i = j = 0
        n = len(nums)
        while j<n:
            if nums[j]==0:
                i +=1
                j +=1
            else:
                nums[j-i] = nums[j]
                j+=1
        while i>0:
            nums[n-i] = 0
            i -=1

接着试着优化,想把这两个一步做,但是不行,下面是错误示范:

错误示范,搬运和重写不能同时进行,末尾的非0数会丢失掉
class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        i = j = 0
        n = len(nums)
        while j<n-i:
            if nums[j]==0:
                i +=1
                nums[n-i] = 0
            else:
                nums[j-i] = nums[j]
        j+=1

最后是官方的比较巧妙的解答,一次循环完成。

同时swap,或者python里面的交换,速度还是很快的,对于性能提升有帮助,相比于分两次写操作,优先考虑交换。

整体上是双指针的思想,以及顺序处理的思想。构造快慢两个指针,快指针表示处理完成的末端;慢指针表示非0的末端,然后遇到新的数,通过交换到合适的位置,来迭代完成处理。

注意,因为这里后一个序列全部都是0,可以这么做。如果前面是正数序列,后面不是0序列是非负数序列,那么最后你会发现由于交换次数不一定和非负数序列个数相同,那么最后非负数序列的顺序会变掉的,因此这样的方法可以保存前面一个序列的顺序,但是保存不了后面一个序列的顺序。算是局限性吧。代码在下面:

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        n = len(nums)
        left = right = 0
        while right < n:
            if nums[right] != 0:
                nums[left], nums[right] = nums[right], nums[left]
                left += 1
            right += 1

# 作者:LeetCode-Solution
# 链接:https://leetcode-cn.com/problems/move-zeroes/solution/yi-dong-ling-by-leetcode-#solution/
# 来源:力扣(LeetCode)

官方给的解析:

方法一:双指针
思路及解法

使用双指针,左指针指向当前已经处理好的序列的尾部,右指针指向待处理序列的头部。

右指针不断向右移动,每次右指针指向非零数,则将左右指针对应的数交换,同时左指针右移。

注意到以下性质:

左指针左边均为非零数;

右指针左边直到左指针处均为零。

因此每次交换,都是将左指针的零与右指针的非零数交换,且非零数的相对顺序并未改变

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/move-zeroes/solution/yi-dong-ling-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值