💡

为什么需要模板?

算法模板帮助你快速识别问题类型,提供标准化的解题思路和代码框架。 掌握模板后,遇到新题时只需套用并微调,大大降低做题难度。

选择模板

📝

双指针

使用两个指针从不同位置遍历数组,常用于有序数组、链表问题

🔑 识别关键词(看到这些词就想到这个模板)

有序数组两数之和回文反转合并去重移动零
时间复杂度:O(n)
空间复杂度:O(1)

🧠思维步骤(按这个顺序思考)

1

确定指针类型

判断使用哪种双指针模式

💭 需要从两端向中间?还是同向移动?

例:对撞指针:回文、两数之和 | 快慢指针:去重、移动零

2

确定初始位置

设定两个指针的起始位置

💭 指针应该从哪里开始?

例:对撞:left=0, right=n-1 | 快慢:slow=0, fast=0

3

确定移动条件

什么情况下移动哪个指针

💭 什么时候移动 left?什么时候移动 right?

例:两数之和:sum < target 移动 left,sum > target 移动 right

4

确定终止条件

循环何时结束

💭 指针相遇?还是遍历完成?

例:while (left < right) 或 while (fast < n)

💻代码模板

typescript
1function twoPointers(arr: number[]): number[] {
2  // 1. 初始化双指针
3  let left = 0;              // 左指针从头开始
4  let right = arr.length - 1; // 右指针从尾开始
5
6  // 2. 循环直到指针相遇
7  while (left < right) {
8    // 3. 计算当前状态(如:两数之和)
9    const current = arr[left] + arr[right];
10
11    // 4. 根据条件判断移动哪个指针
12    if (current < target) {
13      // 需要更大的值,移动左指针
14      left++;
15    } else if (current > target) {
16      // 需要更小的值,移动右指针
17      right--;
18    } else {
19      // 找到答案
20      return [left, right];
21    }
22  }
23
24  return [-1, -1]; // 未找到
25}

⚠️常见错误(避坑指南)

高频边界条件错误
❌ 错误写法
while (left <= right)
✅ 正确写法
while (left < right)

对撞指针用 <,相等时已经处理完所有元素

高频忘记移动指针
❌ 错误写法
if (condition) { /* 处理 */ }
✅ 正确写法
if (condition) { /* 处理 */ left++; }

处理完当前元素后必须移动指针,否则死循环

中频指针初始化错误
❌ 错误写法
right = arr.length
✅ 正确写法
right = arr.length - 1

数组索引从0开始,最后一个元素索引是 length-1