611. 有效三角形的个数 - 力扣

611. 有效三角形的个数 - 力扣(LeetCode)


给定一个包含非负整数的数组 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

Solution

  • 假设三角形的三个边是 a<=b<=c,他们需要满足 b-a <c< a+b,才能构成三角形
  • 对数组排序,对于固定的 nums[i]=a, nums[j]=b ,需要找到满足要求的c,第一个不等式显然是满足的,所以只需要找到最大的小于 a+b 的 nums[k]=c,此时 [j+1,k] 中间的数都满足三角形的边长要求
  • 而且在 j++ 进入下一轮搜索之后,c 的坐标只可能大于上一轮 nums[k]=c 的坐标,利用这一点可以缩小 k 的搜索范围
  • j 从 i+1 遍历到 n 时,k 最多也只会搜索过 n 次,均摊下来 j 每次遍历 k 只搜索了一次,均摊复杂度为 o(n)
  • 所以总时间复杂度是 o ( n 2 ) o(n^2) o(n2)
  • 由于用到了排序,所以空间复杂度 o(logn)
class Solution {
    
    
public:
    int triangleNumber(vector<int>& nums) {
    
    
        sort(nums.begin(), nums.end());
        int ans = 0;
        for(int i=0; i<nums.size(); i++){
    
    
            int k=i+1;
            for(int j=i+1; j<nums.size(); j++){
    
    
               while(k<nums.size() && nums[k]<nums[i]+nums[j]){
    
    
                   k++;
               }
               if(k>j) ans+=(k-j-1);
            }
        }
        return ans;
    }
};

猜你喜欢

转载自blog.csdn.net/aiyolo/article/details/126443548