双指针是一种高效解决问题的算法思想,主要分为以下两类:
解题思路:
fast
和慢指针 slow
,均从链表头部开始。fast == nullptr
),则链表无环。C++ 实现:
class Solution {
public:
bool hasCycle(ListNode *head) {
ListNode *slow = head, *fast = head; // 初始化快慢指针
while (fast && fast->next) { // 快指针和其下一节点不为空
slow = slow->next; // 慢指针走一步
fast = fast->next->next; // 快指针走两步
if (fast == slow) // 相遇,说明有环
return true;
}
return false; // 快指针走到链表末尾,无环
}
};
C 语言实现:
typedef struct ListNode ListNode;
bool hasCycle(struct ListNode *head) {
ListNode *slow = head, *fast = head; // 初始化快慢指针
while (fast && fast->next) { // 快指针和其下一节点不为空
slow = slow->next; // 慢指针走一步
fast = fast->next->next; // 快指针走两步
if (fast == slow) // 相遇,说明有环
return true;
}
return false; // 快指针走到链表末尾,无环
}
解题思路:
fast
和慢指针 slow
,均从链表头部开始。C++ 实现:
class Solution {
public:
ListNode* middleNode(ListNode* head) {
ListNode *slow = head, *fast = head; // 初始化快慢指针
while (fast && fast->next) { // 快指针和其下一节点不为空
slow = slow->next; // 慢指针走一步
fast = fast->next->next; // 快指针走两步
}
return slow; // 返回中间节点
}
};
C 语言实现:
typedef struct ListNode ListNode;
struct ListNode* middleNode(struct ListNode* head) {
ListNode *slow = head, *fast = head; // 初始化快慢指针
while (fast && fast->next) { // 快指针和其下一节点不为空
slow = slow->next; // 慢指针走一步
fast = fast->next->next; // 快指针走两步
}
return slow; // 返回中间节点
}
解题思路:
left
和 right
,分别指向数组的最左端和最右端。right - left
,高度由两指针指向的值中较小的决定,即 min(height[left], height[right])
。v = (right - left) * min(height[left], height[right])
。注意:
C++ 实现:
class Solution {
public:
int maxArea(vector<int>& height) {
int left = 0, right = height.size() - 1, ret = 0; // 初始化指针和结果
while (left < right) { // 指针未相遇
int v = min(height[left], height[right]) * (right - left); // 容积
ret = max(ret, v); // 更新最大容积
if (height[left] < height[right]) // 移动较小高度的指针
left++;
else
right--;
}
return ret;
}
};
C 语言实现:
#define MIN(a, b) ((b) < (a) ? (b) : (a))
#define MAX(a, b) ((b) > (a) ? (b) : (a))
int maxArea(int* height, int heightSize) {
int ans = 0, left = 0, right = heightSize - 1; // 初始化指针和结果
while (left < right) { // 指针未相遇
int area = (right - left) * MIN(height[left], height[right]); // 容积
ans = MAX(ans, area); // 更新最大容积
if (height[left] < height[right]) // 移动较小高度的指针
left++;
else
right--;
}
return ans;
}
解题思路:
nums[i] + nums[left] > nums[right]
,则可以组成三角形。left
不断接近 i
,逐步找到所有满足条件的组合。C++ 实现:
class Solution {
public:
int triangleNumber(vector<int>& nums) {
sort(nums.begin(), nums.end()); // 数组排序
int ret = 0, n = nums.size();
for (int right = n - 1; right >= 2; right--) { // 固定最长边
int left = 0, i = right - 1; // 初始化左右指针
while (left < i) { // 左右指针未相遇
if (nums[i] + nums[left] > nums[right]) { // 满足三角形条件
ret += i - left; // 统计可以组成三角形的数量
i--; // 缩小右边
} else {
left++; // 增大左边
}
}
}
return ret;
}
};