💡
为什么需要模板?
算法模板帮助你快速识别问题类型,提供标准化的解题思路和代码框架。 掌握模板后,遇到新题时只需套用并微调,大大降低做题难度。
选择模板
📝
双指针
使用两个指针从不同位置遍历数组,常用于有序数组、链表问题
🔑 识别关键词(看到这些词就想到这个模板)
有序数组两数之和回文反转合并去重移动零
时间复杂度: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