双指针算法进阶:三角形计数与多数之和
双指针是处理有序数组问题的利器。当数据规模较大时,暴力枚举往往超时,而利用单调性配合双指针可以将复杂度从 O(N^2) 甚至 O(N^3) 降低到 O(N^2)。下面我们通过四个由浅入深的经典题,梳理这一思想的核心逻辑。
有效三角形个数
问题描述
给定一个包含非负整数的数组,统计其中能组成三角形的三元组个数。
解题思路
构成三角形的条件是任意两边之和大于第三边。若将三边设为 a, b, c,且 c 为最长边,则只需满足 a + b > c。
为了高效查找,我们先对数组进行升序排序。固定最大边 nums[i],使用双指针 left 和 right 分别在剩余区间两端寻找满足条件的组合。
由于数组已排序,若 nums[left] + nums[right] > nums[i],则对于当前 right 而言,left 到 right-1 之间的所有元素与 nums[right] 相加均大于 nums[i]。此时可直接累加 right - left 个解,并将 right 左移继续尝试。反之,若和小于等于第三边,则需增大最小边,将 left 右移。

代码示例
class Solution {
public:
int triangleNumber(vector<int>& nums) {
sort(nums.begin(), nums.end());
int count = 0;
// 从右往左依次将最大值作为第三边
for(int i = nums.size() - 1; i >= 2; i--) {
int left = 0;
int right = i - ;
(left < right) {
(nums[left] + nums[right] > nums[i]) {
count += right - left;
right--;
} {
left++;
}
}
}
count;
}
};




