给定一个包含非负整数的数组 nums
,返回其中可以组成三角形三条边的三元组个数。
示例 1:
输入: nums = [2,2,3,4]
输出: 3
解释:有效的组合是:
2,3,4 (使用第一个 2)
2,3,4 (使用第二个 2)
2,2,3
示例 2:
输入: nums = [4,2,3,4]
输出: 4
提示:
1 <= nums.length <= 1000
0 <= nums[i] <= 1000
Solution
- 假设三角形的三个边是 a<=b<=c,他们需要满足 b-a <c< a+b,才能构成三角形
- 对数组排序,对于固定的 nums[i]=a, nums[j]=b ,需要找到满足要求的c,第一个不等式显然是满足的,所以只需要找到最大的小于 a+b 的 nums[k]=c,此时 [j+1,k] 中间的数都满足三角形的边长要求
- 而且在 j++ 进入下一轮搜索之后,c 的坐标只可能大于上一轮 nums[k]=c 的坐标,利用这一点可以缩小 k 的搜索范围
- j 从 i+1 遍历到 n 时,k 最多也只会搜索过 n 次,均摊下来 j 每次遍历 k 只搜索了一次,均摊复杂度为 o(n)
- 所以总时间复杂度是 o ( n 2 ) o(n^2) o(n2)
- 由于用到了排序,所以空间复杂度 o(logn)
class Solution {
public:
int triangleNumber(vector<int>& nums) {
sort(nums.begin(), nums.end());
int ans = 0;
for(int i=0; i<nums.size(); i++){
int k=i+1;
for(int j=i+1; j<nums.size(); j++){
while(k<nums.size() && nums[k]<nums[i]+nums[j]){
k++;
}
if(k>j) ans+=(k-j-1);
}
}
return ans;
}
};