[LeetCode][Golang] 283.移动零

该博客介绍了如何使用Golang解决LeetCode中的283题,即移动零到数组末尾并保持非零元素相对顺序的问题。通过设置循环不变式,博主提供了两种解题思路:一种是使用交换操作,另一种是直接赋值。两种方法的时间复杂度都是O(n),空间复杂度为O(1)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

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

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

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

题解:

首先,这是一道数组类的简单算法题。我们明确循环不变式(loop invariant)的概念,即一组在循环体内、每次迭代均保持为真的性质。

先贴代码:(GO语言)

func moveZeroes(nums []int) {
   left, right, n := 0, 0, len(nums)
   for right < n {
      if nums[right] != 0 {
         nums[left], nums[right] = nums[right], nums[left]
         left++
      }
      right++
   }
}

我们设置的循环不变式:left指针之前的数组元素(不包含目前所指元素)不为0

  • 初始left设为0,即nums[0]之前的元素不为0,由于nums[0]之前没有元素,left位置满足不变式要求。
  • 接下来的循环中,如果nums[right]不为0,则与nums[left]进行交换后后移left,结束本次循环。如果nums[right]0,则直接结束本次循环。每次循环,left位置均满足不变式要求。
  • 最终right指针遍历完数组元素后,结束整个循环,left位置满足不变式要求。

因此在循环结束后,left左侧元素均为非0元素,且由于right按数组顺序遍历,非0元素保持原数组的有序性,符合算法要求。

更容易理解的是,循环中也可不使用交换,而是如果nums[right]不为0,直接赋值给nums[left]right的循环结束后,多写一个循环,将leftleft之后的数组元素置零。

复杂度分析:

  • 时间复杂度:O(n),其中n为序列长度。每个位置至多被遍历两次。
  • 空间复杂度:O(1)。只需要常数的空间存放若干变量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值