双指针算法进阶:三角形计数与多数求和
在算法面试中,双指针配合排序往往能解决很多看似复杂的问题。今天我们来深入探讨几个经典场景,看看如何通过单调性优化暴力解法。
有效三角形个数
题目描述
给定一个包含非负整数的数组,找出其中能构成三角形的三元组个数。
解题思路
构成三角形的核心条件是任意两边之和大于第三边。如果我们将三边设为 a, b, c(假设 c 为最长边),那么只需满足 a + b > c 即可。
为了高效判断,我们可以先对数组进行升序排序。这样,对于固定的最大边 nums[i],我们只需要在左侧区间寻找两个数,使它们的和大于 nums[i]。
具体做法是:固定右边界 i 作为最长边,左指针 left 指向开头,右指针 right 指向 i-1。如果 nums[left] + nums[right] > nums[i],说明从 left 到 right-1 的所有元素与 nums[right] 组合都能满足条件(因为数组有序),此时累加 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 - 1;
while (left < right) {
if (nums[left] + nums[right] > nums[i]) {
// 若满足条件,则 [left, right-1] 均满足
count += right - left;
right--;
} else {
left++;
}
}
}
count;
}
};




