在C++中,双指针通常指的是两个指针分别从数组或者序列的两端向中间移动,或者在链表中一前一后同时移动的技巧。这种方法常用于解决数组或链表中的一些问题,例如查找两个数之和、反转链表、判断链表是否有环等。以下是一些常见问题的双指针解法思路:
1. 数组问题:查找两个数之和
问题描述:给定一个已排序的整数数组 nums,找出数组中两个数使它们的和等于目标值 target。
思路:
1.使用两个指针,一个指向数组的起始位置(left),另一个指向数组的末尾(right)。
2.比较 nums[left] + nums[right] 与 target 的大小关系:
3.如果等于 target,则找到了这两个数。
4.如果小于 target,将 left 指针右移一位,使得和变大。
5.如果大于 target,将 right 指针左移一位,使得和变小。
6.重复上述步骤直到找到答案或者 left 指针大于等于 right。
vector<int> twoSum(vector<int>&nums, int target) {
int left = 0, right = nums.size() - 1;
while (left<=right) {
int sum = nums[left] + nums[right];
if (sum == target) {
return {nums[left], nums[right]};
} else if (sum<target) {
left++;
} else {
right--;
}
}
// If no such pair found
return {};
}
2. 链表问题:判断链表是否有环
问题描述:判断给定的链表中是否有环。
思路:
7.使用两个指针,一个慢指针 slow,每次移动一步,一个快指针 fast,每次移动两步。
8.如果链表中有环,快指针 fast 最终会追上慢指针 slow。
9.如果链表中没有环,快指针 fast 会先到达链表尾部,结束循环。
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(nullptr) {}
};
bool hasCycle(ListNode *head) {
if (!head || !head->next) {
return false;
}
ListNode *slow = head;
ListNode *fast = head->next;
while (slow != fast) {
if (!fast || !fast->next) {
return false;
}
slow = slow->next;
fast = fast->next->next;
}
return true;
}
这些例子展示了双指针技巧在不同问题中的应用,通过同时移动两个指针,可以在较低的时间复杂度内解决一些常见的算法问题。