1. 双指针算法基础认知
第一次听说"双指针"这个术语时,我误以为是要操作实际的物理指针。后来在解决LeetCode第27题移除元素时,才真正理解这种算法的精妙之处。双指针本质上是通过两个动态移动的索引来协同处理数据,这种思想在数组操作中尤为高效。
数组分块是双指针最典型的应用场景之一。比如我们需要将数组中的奇偶数分开,或者把零元素移到末尾。传统做法可能需要多次遍历或额外空间,而双指针可以在O(n)时间复杂度、O(1)空间复杂度内完成。这让我想起整理书架的经历——与其把所有书搬出来分类,不如直接在书架上交换位置来得高效。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 快慢指针实现数组划分
2.1 基础快慢指针模型
最常见的快慢指针实现如下:
python复制def partition(nums):
slow = 0
for fast in range(len(nums)):
if need_keep(nums[fast]): # 判断条件
nums[slow], nums[fast] = nums[fast], nums[slow]
slow += 1
这个模板中,fast指针负责扫描整个数组,slow指针标记待插入位置。当fast遇到需要保留的元素时,就与slow位置交换。这种模式在以下场景特别有效:
- 移动零(LeetCode 283)
- 删除指定值(LeetCode 27)
- 去重问题(LeetCode 26)
2.2 条件判断的优化技巧
need_keep()函数的实现直接影响算法效率。以奇偶分离为例:
python复制# 常规写法
if nums[fast] % 2 == 1: ...
# 位运算优化
if nums[fast] & 1: ...
在算法竞赛中,这类微优化可能带来显著性能提升。我曾在一个百万级数据量的测试用例中,通过位运算将运行时间从480ms降到420ms。
3. 左右指针的进阶应用
3.1 双向扫描策略
当需要对数组进行分块排序时,左右指针往往更高效。荷兰国旗问题就是典型例子:
python复制def sortColors(nums):
left, curr, right = 0, 0, le
