问题描述
给定一个包含非负整数的数组,你的任务是统计其中可以组成三角形三条边的三元组个数。
示例 1:
输入: [2,2,3,4]
输出: 3
解释:
有效的组合是:
2,3,4 (使用第一个 2)
2,3,4 (使用第二个 2)
2,2,3
注意:
数组长度不超过1000。
数组里整数的范围为 [0, 1000]。
解题报告
暴力解决的时间复杂度为
O
(
n
3
)
O(n^3)
O(n3)
可以通过排序减少时间复杂度。
排序后,当选定两个数之后:
- 如果第三个数的索引边界通过二分查找,将时间复杂度降到 O ( n 2 l o g n ) O(n^2logn) O(n2logn)
- 三个数的索引分别是
i
、j
、k
,当选定i
、j
时,搜索到k
的索引边界为 k 1 k_1 k1,那么j
变成j+1
时,k
的起始索引可以从 k 1 k_1 k1 开始。时间复杂度降到了 o ( n 2 ) o(n^2) o(n2)。这种方法咋一看,会以为时间复杂度依然是 O ( n 3 ) O(n^3) O(n3),但初始感觉是错的。
实现代码
class Solution {
public:
int triangleNumber(vector<int>& nums) {
sort(nums.begin(), nums.end());
int n=nums.size(), ans =0;
for(int i=0;i<n-2;i++){
if(nums[i]==0)continue;
int k=i+2;
for(int j=i+1;j<n-1;j++){
while(k<n&&nums[i]+nums[j]>nums[k]) k++;
ans+=(k-j-1);
}
}
return ans;
}
};