双指针应用场景
双指针是算法面试中的高频考点,尤其在处理有序数组或需要优化查找效率的场景下表现优异。本篇通过两个经典例题,深入剖析对撞指针的实际应用。
1. 有效三角形个数
题目描述
给定一个包含非负整数的数组 nums,统计其中能组成三角形的三元组个数。
思路解析
构成三角形的条件是任意两边之和大于第三边。如果我们将三个数从小到大排序为 a, b, c,那么只需满足 a + b > c 即可(因为 c 最大,其他不等式自然成立)。
暴力枚举需要 O(n³),我们可以利用排序和对撞指针将复杂度降至 O(n²)。
- 排序:先将数组升序排列。
- 固定最长边:从后往前遍历,固定
nums[i]作为三角形的最长边。 - 双指针查找:在
[0, i-1]区间内使用左右指针left和right。- 若
nums[left] + nums[right] > nums[i],说明当前right与left到right-1之间的所有元素都能与nums[i]构成三角形。此时计数增加right - left,并将right左移尝试更小的组合。 - 若
nums[left] + nums[right] <= nums[i],说明两边之和太小,需增大较小边,将left右移。
- 若
核心实现
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Solution {
public:
int triangleNumber(vector<int>& nums) {
sort(nums.begin(), nums.end()); // 升序排序
int n = nums.size();
int ret = 0;
( i = n - ; i >= ; i--) {
left = , right = i - ;
(left < right) {
(nums[left] + nums[right] > nums[i]) {
ret += right - left;
right--;
} {
left++;
}
}
}
ret;
}
};


