题目
给定一个包含非负整数的数组 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
提交代码
//有效三角形的个数
//两次双指针
//求可以组成三角形的个数
//合法的三边:两边之和大于第三边
//数组排序,从小到大
//三个元素之间的关系
//假设第一条边最长,边2+边3>边1这种情况可以后再试其他位置
//边2<=边3
//不排除相等边
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> nums;//整数数组
int result = 0;//结果
int n;//整数个数
//两次双指针
void tn(){
int i = n - 1;//边1指针,向左走
//确定可能的边1
while(i > 1){
if(nums[i - 1] + nums[i - 2] <= nums[i]){
//nums[i]为最长边时没有答案了
i--;
}else if(nums[i - 1] + nums[i - 2] > nums[i]){
//确定边2和边3
int j = 0,k = i - 1;//边2和边3指针
//假设边2<边3
while(j < k){
if(nums[j] + nums[k] <= nums[i]){
j++;
}else if(nums[j] + nums[k] > nums[i]){
int m = j;
result += (k - j);
k--;
}
}
i--;
}
}
}
int main(){
//输入整数数组
int t;
while(cin.peek() != '\n'){
scanf("%d",&t);
nums.push_back(t);
}
//-------------------------------
n = nums.size();//整数个数
//数组排序
sort(nums.begin(),nums.end());
//两次双指针
tn();
//输出结果
printf("%d",result);
return 0;
}
总结
解题思路:合理的三角形两边之和小于第三边,判断是否是合理三角形的时候只要判断最长边为第三边的情况就可以,求的是三角形的个数,可以利用两次双指针优化查找时间。首先确定可能的最长边,然后确定可能的另两条边。
注意:一定要先审清题意,明确到底什么是合理情况!!!