提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
前言
世上有两种耀眼的光芒,一种是正在升起的太阳,一种是正在努力学习编程的你!一个爱学编程的人。各位看官,我衷心的希望这篇博客能对你们有所帮助,同时也希望各位看官能对我的文章给与点评,希望我们能够携手共同促进进步,在编程的道路上越走越远!
提示:以下是本篇文章正文内容,下面案例可供参考
一、有效三角形的个数(medium)
1.1、题目
1.2、讲解算法原理
补充数学知识:给我们三个数,判断是都能够构成三角形。
步骤:利用单调性,使用双指针算法来解决问题。
- 先固定最大的数;
- 在最大的数的左区间内,使用双指针算法,快速统计出符合要求的三元组的个数。
来举例一个区间[2,2,3,4,4,9,10]来说明一下情况:
- 优化:先对整个数组排序,用于固定最大的数。
- 我们根据三角形的满足条件得出的两个结论:因为数组是升序的,所以设a和b为最小的两边,c为最大的边,a + b > c就能构成三角形;a + b <= c便不能构成三角形。
- 我们使用双指针的思想,假设数组的下标为指针,设left指针指向数组下标为0的位置,设right指针指向数组中最大的数的左区间中的最大值。
- 拿上面的数组为例,先固定最大的数为10,设left为第一个2所在的位置,right为9所在的位置,left + right大于10,因为是升序,所以当right不变,left指向2~9之间的任意数时,都符合三角形的条件,因此得出的结论:下标right - left的值为满足三角形的情况,9所在的位置可以划掉,right--。
- 此时left为第一个2,right为5,最大值依旧为10:2 + 5 < 10,不构成三角形的条件,left++,再次判断三角形的条件,重复操作,直到left和right相遇,最大值为10所在的情况查看完毕,更新最大值。
1.3、编写代码
class Solution
{
public:
int triangleNumber(vector<int>& nums)
{
// 先进行排序
sort(nums.begin(), nums.end());
// 利用双指针解决问题
int ret = 0, 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;
}
};