双指针技巧是一种非常实用的解决数组和链表问题的方法。其基本思想是使用两个指针,而不是一个,以便更有效地满足问题的要求。
双指针从数组两侧向中间靠拢(常用于有序数组):
function twoPointerMethod(arr, target) {
let left = 0; // 左指针从0开始
let right = arr.length - 1; // 右指针从数组的最后一个元素开始
while (left < right) {
let sum = arr[left] + arr[right];
if (sum === target) {
return [left, right]; // 找到目标值,返回两个指针的位置
} else if (sum < target) {
left++; // 如果和小于目标值,左指针右移
} else {
right--; // 如果和大于目标值,右指针左移
}
}
return [-1, -1]; // 没找到目标值,返回[-1, -1]
}
快慢双指针(常用于链表中):
function hasCycle(head) {
if (!head || !head.next) return false;
let slow = head; // 慢指针每次移动一步
let fast = head.next; // 快指针每次移动两步
while (slow !== fast) { // 当两个指针相遇时,表示存在环
if (!fast || !fast.next) return false;
slow = slow.next;
fast = fast.next.next;
}
return true;
}
常见题型
- 两数之和:在有序数组中找到两个数,使它们的和等于目标值。
- 反转字符串:使用双指针从两侧向中间移动,交换字符。
- 验证回文字符串:使用双指针从两侧向中间移动,检查每对字符是否相等。
- 移除元素:在数组中移除给定的元素,并返回新的长度。
- 链表中的环检测:使用快慢双指针技巧检测链表中是否存在环。
- 找到链表的中点:使用快慢双指针。
- 链表的倒数第k个节点:使用间隔为k的双指针。
这只是双指针技巧的一些基本应用。在实际问题中,您可能需要结合其他数据结构和技巧来求解。