【力扣-283. 移动零】Python笔记
双指针法概述
适用场景判断使用双指针的典型信号:
题目要求 “原地修改”(不使用额外空间)
题目给出有序数组
要求保持 “相对顺序”
题目和两端比较有关
双指针分类
| 类型 | 核心思想 | 典型应用 |
|---|---|---|
| 对向指针 | 一个从左到右,一个从右到左,向中间移动 | 两数之和、盛最多水的容器、反转数组 |
| 快慢指针 | fast 指针遍历数组,slow 指针记录有效位置 |
移除元素、删除链表重复节点、环形链表 |
| 左右指针 | left 找最左,right 找最右,向中间逼近 |
二分查找变种、最长回文子串 |
| 单指针 | 遍历数组,在不额外空间下完成操作 | 简单原地修改场景 |
经典算法题:移动零(LeetCode 283)
题目描述:给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序,且必须原地修改数组。
示例:
输入:nums = [0, 1, 0, 3, 12]
输出:[1, 3, 12, 0, 0]
快慢指针解法(时间 O(n),空间 O(1))
核心思路:slow 指针:记录下一个非零元素应该放置的位置fast 指针:遍历整个数组,寻找非零元素
遇到非零元素时,将其赋值到 slow 位置,然后 slow 前进
遍历结束后,slow 之后的位置全部补 0
from typing import List
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""Do not return anything, modify nums in-place instead."""
slow = 0 # 记录非零元素该放的位置
# fast 指针遍历整个数组
for fast in range(len(nums)):
if nums[fast] != 0: # 将非零元素移动到 slow 指针位置
nums[slow] = nums[fast]
slow += 1
# 前面的非零元素已处理完,剩下的位置全部补 0
for i in range(slow, len(nums)):
nums[i] = 0
代码执行示例
以 nums = [2, 0, 3, 0, 9] 为例:fast=0:nums[0]=2≠0 → nums[0]=2,slow=1fast=1:nums[1]=0 → 跳过fast=2:nums[2]=3≠0 → nums[1]=3,slow=2fast=3:nums[3]=0 → 跳过fast=4:nums[4]=9≠0 → nums[2]=9,slow=3
补零:nums[3] = 0,nums[4] = 0
最终数组:[2, 3, 9, 0, 0]
双指针核心技巧总结
对向指针(左右指针)
初始化:left = 0,right = len(nums) - 1
循环条件:while left <= right
移动逻辑:根据比较结果,让 left 右移或 right 左移,向中间逼近
快慢指针
初始化:slow = 0,fast 从 0 开始遍历
核心:fast 负责探索,slow 负责收集有效结果
典型操作:覆盖 / 交换,实现原地修改
指针操作本质
一次遍历:避免嵌套循环,时间复杂度优化到 O(n)
不额外数组:空间复杂度优化到 O(1)
整理结果:遍历完成后,对剩余位置做统一处理(如补零)
双指针适用场景速查
| 场景 | 指针类型 | 典型题目 |
|---|---|---|
| 原地修改数组 | 快慢指针 | 移动零、移除元素 |
| 有序数组找目标 | 对向指针 | 两数之和 II、三数之和 |
| 链表操作 | 快慢指针 | 环形链表、中间节点 |
| 字符串反转 | 对向指针 | 反转字符串、验证回文 |
更多推荐


所有评论(0)