mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6
566 字
1 分钟
移动零
2026-06-17

题目描述#

题目链接

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

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

输入#

整数数组 nums

输出#

无返回值,原地修改 nums

约束条件#

  1. 1 <= nums.length <= 10^4
  2. -2^31 <= nums[i] <= 2^31 - 1

进阶约束#

  1. 能否尽量减少操作次数?

示例1#

input: nums = [0,1,0,3,12]
output: [1,3,12,0,0]

示例2#

input: nums = [0]
output: [0]

解题思路#

题目要求把数组中的 0 全部挪到末尾,同时非零元素之间的相对顺序不能变,并且必须原地修改,不能另开数组。

从直观做法出发#

最容易想到的是:先统计 0 的个数,再把非零元素按顺序填到前面,最后把剩余位置全部填 0。思路没问题,但通常需要额外数组或两次遍历,不够简洁。

另一种想法是:从左到右扫描,每遇到一个非零元素,就把它「写」到当前应该存放的位置。非零元素按扫描顺序依次写入,空出来的位置自然就是 0 了——这正是双指针能做的事。

双指针:一个扫描,一个写入#

用两个指针 ij,初始都为 0

  • i:从左到右扫描整个数组
  • j:指向下一个非零元素应该写入的位置

遍历过程中,若 nums[i] 非零,就把它交换到 nums[j],然后 j 加一;若 nums[i] 为零,则什么都不做,继续让 i 往后走。

nums = [0, 1, 0, 3, 12] 为例:

inums[i]操作numsj
00跳过[0,1,0,3,12]0
11交换 nums[1]nums[0][1,0,0,3,12]1
20跳过[1,0,0,3,12]1
33交换 nums[3]nums[1][1,3,0,0,12]2
412交换 nums[4]nums[2][1,3,12,0,0]3

遍历结束后,j 之后的元素本来就是 0 或被交换过来的 0,上表最后一行即为最终结果。

i == j 时交换等于没交换,因此非零元素在「前面没有零」的情况下不会被多余地移动,相对顺序也始终得以保持。

复杂度#

  • 时间复杂度:O(n)O(n),只遍历数组一次
  • 空间复杂度:O(1)O(1),仅使用常数额外空间

代码#

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

如果这篇文章对你有帮助,欢迎分享给更多人!

移动零
https://www.hygen.red/posts/hot100/02-双指针/004-移动零/
作者
Hygen
发布于
2026-06-17
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录