一.题目
习题链接:611. 有效三角形的个数 - 力扣(LeetCode)

二.题目讲解

注意:重复的也要统计在内
三.算法原理讲解
想要解决这道题首先要明确的是满足三角形的条件:任意两边之和大于第三边,但是这需要三个条件,我们可以简化为一个条件,即两个较小数之和大于最大的那一个就可以
我们首相想到的就是把所有情况都给遍历一遍,然后统计个数,但是这样效率会很低,这里我们利用双指针来实现:
下面我们举例分析:

首先我们需要将数组进行排列,然后定住最右边的那个数(10),给出两个指针一个指向最左边(2),一个指向最右边小于最大那个数(9),当left和right指向的两个数相加会出现两种情况:
一种是 a+b>c 可以构成三角形 ;另一种是 a+b<=c 不可以构成三角形
第一种:由于2+9已经大于10了,数组又是按升序排列,所以 2 , 9之间的数都要比2大,中间的数与9相加都会大于10,这时中间的数任意一个和9,10组合都能构成三角形,所以构成三角形的个数就是 right-left ,然后让 right-- ,最大数减小再次判断是否还大于c
第二种:由于2+9已经大于10了,数组又是按升序排列,所以 2 , 9之间的数都要比9小,中间的数与2相加都会小于10,这时中间的数任意一个和9,10组合都不能构成三角形,所以这时就需要让最小数left++,指向更大的数再次与9相加判断是否大于10
第一层循环结束的条件是 left >= right 这时说明以10为基准数的情况已经遍历完了,然后让c--,再次循环来找可以组合的情况

四.编写代码
cpp
class Solution {
public:
int triangleNumber(vector<int>& nums) {
sort(nums.begin(),nums.end());
int num = 0;
int c = nums.size() - 1;
while(c > 1)
{
int left = 0, right = c - 1;
while(left < right)
{
if(nums[left] + nums[right] > nums[c])
{
num += right - left;
right--;
}
else
{
left++;
}
}
c--;
}
return num;
}
};