双指针算法实战
双指针是处理有序数组问题的利器。通过利用数据的单调性,我们可以将原本需要 O(n²) 甚至 O(n³) 的暴力解法优化到 O(n) 或 O(n²)。本文将结合四个经典例题,深入讲解双指针在不同场景下的应用技巧。
【611.有效三角形个数】
题目描述
给定一个包含非负整数的数组,统计其中能构成三角形的三元组个数。
核心思路
构成三角形的条件是任意两边之和大于第三边。对于排序后的数组,若固定最长边 c,只需满足 a + b > c 即可(其中 a, b 为较短两边)。因此,我们可以先对数组升序排序,然后从右向左遍历,将当前元素视为最长边,利用双指针在左侧寻找满足条件的组合。
实现细节
- 排序:首先将数组按升序排列。
- 固定最大边:从倒数第三个元素开始向前遍历,设当前索引为
i。 - 双指针查找:左指针
left指向起始位置,右指针right指向i-1。- 若
nums[left] + nums[right] > nums[i],说明left到right-1之间的所有元素与right都能与nums[i]构成三角形,数量为right - left。随后right--继续尝试更小的最长边。 - 若和小于等于
nums[i],则需增大较短边,即left++。
- 若
- 去重与边界:注意
right >= left时停止循环,且i至少为 2。

代码实现
class Solution {
public:
int triangleNumber(vector<int>& nums) {
sort(nums.begin(), nums.end()); // 升序排序
int count = ;
( i = nums.() - ; i >= ; i--) {
left = ;
right = i - ;
(left < right) {
(nums[left] + nums[right] > nums[i]) {
count += right - left;
right--;
} {
left++;
}
}
}
count;
}
};




