(day21)leecode100. 移动零

描述

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

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

示例 1:

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

示例 2:

输入: nums = [0]
输出: [0]

提示:

  • 1 <= nums.length <= 104
  • -231 <= nums[i] <= 231 - 1

进阶:你能尽量减少完成的操作次数吗?

分析

不复制数组:不可以开辟新空间,即不能自定义其他数组(若是无这个条件,可以将非零与零分别放入两个数组,再用(   [非零].extend([零]   )

简洁代码

直接使用python的内置函数remove(0),append(0),一个移除并拼接到末尾即可实现

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
       for i in range(len(nums)):
            if nums[i]==0:
                nums.remove(0)
                nums.append(0)



转自leecode题解Shawxing精讲算法
 

 本篇统一采用如下数组,并且采用双指针。蓝色指针为 l,橙色指针为 r。初始 l,r 的 index 均为 0。

解法一

记元素向左的偏移量为 offset,初始 offset = 0。

每次发现元素为 0 时增加偏移量,发现元素非 0 且偏移量非 0 时偏移元素。

 

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        offset = 0  # 初始化偏移量为0,用于记录遇到的0的个数

        for i in range(len(nums)):  # 遍历整个数组
            if nums[i] == 0:  # 如果当前元素是0
                offset += 1  # 将偏移量加1
            elif offset != 0:  # 如果当前元素不是0且偏移量不为0
                nums[i - offset] = nums[i]  # 将当前元素移动到前面偏移量的位置
                nums[i] = 0  # 将当前元素位置设为0

解法二

 如下所示,我们可以将 l 移动到自身右侧第一个元素为 0 的位置,将 r 移动到 l 右侧第一个元素非 0 的位置,然后交换元素。

然后再执行上一步骤,循环下去,直至r 抵达边界。 

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        l = 0  # 初始化左指针 l 为 0
        r = 0  # 初始化右指针 r 为 0

        while r < len(nums):  # 当右指针 r 小于数组长度时,进行循环
            if r == l or nums[r] == 0:  # 如果右指针和左指针相等,或者右指针指向的元素为0
                r += 1  # 右指针向右移动一位
            elif nums[l] != 0:  # 如果左指针指向的元素不为0
                l += 1  # 左指针向右移动一位
            else:  # 如果左指针指向的元素为0且右指针指向的元素不为0
                nums[l] = nums[r]  # 将右指针指向的元素赋值给左指针指向的位置
                nums[r] = 0  # 将右指针指向的位置设为0

解法三

出发点是记录第一个元素为 0 的位置,并在每次交换元素时更新。
 

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        l = 0  # 初始化左指针 l 为 0

        for r in range(len(nums)):  # 遍历整个数组,右指针 r 从 0 到 len(nums) - 1
            if nums[r] == 0:  # 如果当前元素为 0,则跳过
                continue
            nums[l], nums[r] = nums[r], nums[l]  # 交换左指针 l 和右指针 r 指向的元素
            l += 1  # 左指针 l 右移一位


取示例数组如下所示,分析代码的运行过程。
初始时 Nums[l]=Nums[r]  !=  0,交换不产生影响。l,r 同步前进。

如下所示,在发现元素 0 时,l 保持不变,r 前进至 Nums[r]  != 0。

 

再如下所示,交换元素,l 前进。


此后 r 前进,一直寻找非 0 元素与 l 处的 0 交换即可。

复杂度
以上解法复杂度一致。

时间:Θ(n)
空间:Θ(1)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值