【编程题】有效三角形的个数

文章目录

  • 一、题目
  • 二、算法讲解
  • 三、题目链接
  • 四、补充


一、题目

给定一个包含非负整数的数组 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: 可以通过双指针模拟三层循环的过程,通过一些条件来规避三层循环。

  1. 首先对数据进行升序排序
  2. 将最后也就是最大的数设置为第三条边。
  3. 两个指针left和right分别指向数据开头和最大数的前一个位置
  4. 进行判断:
    如果left和right的和大于最大的数,那么固定right,left++,两数之和都大于最大的数,因为该组数据是升序,这时候就相当于把right这个位置的数的每种可能都遍历了一遍,只要right-left计算一下三角形个数加到一起就行了,之后right–;
    如果left和right的和小于最大的数,那么固定left,right–,每种情况都是小于最大的数的,这时候就相当于把left这个位置的数的每种可能都遍历了一遍,由于这种情况是不满足三角形的,只需要left++就行了。
  5. 最大的数位置-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. 盛最多水的容器


你可能感兴趣的:(c++,开发语言,leetcode)