一、题目
给定一个包含非负整数的数组 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: 暴力枚举,三层循环,得到一个三角形的三条边,然后判断是否为三角形,但是时间复杂度为O(n3),可能会超时。
思路2: 可以通过双指针来模拟三层循环的过程,通过一些条件来规避三层循环。
- 首先对数据进行升序排序
- 将最后也就是最大的数设置为第三条边。
- 两个指针left和right分别指向数据开头和最大数的前一个位置
- 进行判断:
如果left和right的和大于最大的数,那么固定right,left++,两数之和都大于最大的数,因为该组数据是升序,这时候就相当于把right这个位置的数的每种可能都遍历了一遍,只要right-left计算一下三角形个数加到一起就行了,之后right–;
如果left和right的和小于最大的数,那么固定left,right–,每种情况都是小于最大的数的,这时候就相当于把left这个位置的数的每种可能都遍历了一遍,由于这种情况是不满足三角形的,只需要left++就行了。 - 最大的数位置-1,回到步骤3再次进行判断,直到最大数的位置到2(因为从0开始,0、1位置肯定不可能作为三角形最大的边)。
代码:
class Solution {
public:
int triangleNumber(vector<int>& nums) {
sort(nums.begin(),nums.end());
int ret = 0;
int n = nums.size();
for(int i = n-1; i>=2; --i)
{
int left=0,right=i-1;
while(left<right)
{
if((nums[left]+nums[right])>nums[i])
{
ret+=(right-left);
right--;
}
else
{
left++;
}
}
}
return ret;
}
};
三、题目链接
611. 有效三角形的个数
四、补充
类似的题目还有
11. 盛最多水的容器
代码:文章来源:https://www.toymoban.com/news/detail-674249.html
class Solution {
public:
int maxArea(vector<int>& height) {
int left=0,right=height.size()-1;
int ret=0;
while(left<right)
{
int v=min(height[left],height[right])*(right-left);
ret=max(v,ret);
if(height[left]>height[right])
{
right--;
}
else
{
left++;
}
}
return ret;
}
};
剑指 Offer 57. 和为s的两个数字
代码:文章来源地址https://www.toymoban.com/news/detail-674249.html
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int left=0, right=nums.size()-1;
while(left<right)
{
if(nums[left]+nums[right]<target)
{
left++;
}
else if(nums[left]+nums[right]>target)
{
right--;
}
else
{
return {nums[left],nums[right]};
}
}
return {-1,-1};
}
};
到了这里,关于【编程题】有效三角形的个数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!