跳至内容

移动零

LeetCode 283:用快慢指针依次将非零元素交换到前面,让零留在数组末尾。

LeetCode 283 简单 数组
  • 数组
  • 双指针
  • Python

题目:283. 移动零

给定数组 nums,将所有 0 移到末尾,保持非零元素的相对顺序。要求原地操作,不能复制数组。

示例 1:

  • 输入: nums = [0, 1, 0, 3, 12]
  • 修改后: [1, 3, 12, 0, 0]

示例 2:

  • 输入: nums = [0]
  • 修改后: [0]

1. 移动过程

把非零数依次换到前面,零就会留在后面。nums[fast] != 0 判断的是“当前这个数要不要放到前面”。

两个指针都从下标 0 开始:

  • fast:当前读取的位置,每轮前进一步。
  • slow:下一个非零元素要放的位置,放好一个才前进一步。

下面用示例 1 演示。图中 index 是下标、value 是值,箭头标出每次操作前的指针位置。

第 1 轮:fast = 0,读到 0

代码块 Text
1
2
3
4
5
index:  0   1   2   3   4
value:  0   1   0   3   12
        ●───●───●───●───●
fast:   ↑
slow:   ↑

0 != 0 不成立,不交换。slow = 0 不动,fast 移到 1。

第 2 轮:fast = 1,读到 1

代码块 Text
1
2
3
4
5
index:  0   1   2   3   4
value:  0   1   0   3   12
        ●───●───●───●───●
fast:       ↑
slow:   ↑

1 != 0 成立,将 1 与 slow 处的 0 交换。slow 移到 1,fast 移到 2。

第 3 轮:fast = 2,读到 0

代码块 Text
1
2
3
4
5
index:  0   1   2   3   4
value:  1   0   0   3   12
        ●───●───●───●───●
fast:           ↑
slow:       ↑

0 != 0 不成立,不交换。slow = 1 不动,fast 移到 3。

第 4 轮:fast = 3,读到 3

代码块 Text
1
2
3
4
5
index:  0   1   2   3   4
value:  1   0   0   3   12
        ●───●───●───●───●
fast:               ↑
slow:       ↑

3 != 0 成立,将 3 与 slow 处的 0 交换。slow 移到 2,fast 移到 4。

第 5 轮:fast = 4,读到 12

代码块 Text
1
2
3
4
5
index:  0   1   2   3   4
value:  1   3   0   0   12
        ●───●───●───●───●
fast:                   ↑
slow:           ↑

12 != 0 成立,将 12 与 slow 处的 0 交换。slow 移到 3,fast 移到 5,遍历结束。

结果是 [1, 3, 12, 0, 0]。非零元素按读取顺序依次放到前面,因此它们的相对顺序不变。

2. Python 实现

slow 指向要放入的位置,所以先交换,再让 slow 前进。如果两个指针重合,就是与自身交换,数组不变。

代码块 Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
def move_zero(nums):
    slow, fast = 0, 0
    while fast <= len(nums) - 1:
        if nums[fast] != 0:  # 非零元素需要放到前面,零先跳过
            nums[slow], nums[fast] = nums[fast], nums[slow]
            slow += 1  # 放好一个非零元素,再移动到下一格
        fast += 1  # 无论是否为零,都继续读取下一个元素
    return nums


print(move_zero([0, 1, 0, 3, 12]))
运行结果 Text
1
# [1, 3, 12, 0, 0]

3. 复杂度

设 n 为输入数组的长度。

  • 时间复杂度:O(n),遍历一次,每轮最多交换两个元素。
  • 额外空间复杂度:O(1),直接在原数组中交换,只使用常数个辅助变量。

评论

使用 GitHub 登录后参与讨论,评论将公开保存在 GitHub。

阅读到这里时加载评论。