【LeetCode】611.有效三角形的个数

题目

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

题解

排序+二分查找
三角形要满足a+b>c; a+c>b; b+c>a
当排序好之后, a+c>b和b+c>a一定满足, 只需寻找a+b>c

class Solution {
    
    
public:
    int triangleNumber(vector<int>& nums) {
    
    
        int len = nums.size();
        if(len<3)
            return 0;

        sort(nums.begin(),nums.end());
        int result = 0;
        
        for(int i=0;i<len-2;i++)
        {
    
    
            for(int j=i+1;j<len-1;j++)
            {
    
    
                int left = j+1;
                int right = len-1;
                int target = nums[i]+nums[j];
                while(left<=right)
                {
    
    
                    int mid = (left+right)>>1;
                    if(nums[mid]<target)
                    {
    
    
                        left = mid + 1;
                    }
                    else
                    {
    
    
                        right = mid - 1;
                    }
                }
                result+= right-j ;
            }
        }
        return result;
    }
};

排序+双指针
属于暴力的优化
暴力方法是三个循环, 每次都重置k并循环
但是在排序好的序列中, 因为是递增的, 所以a+b也是递增的, 也就是说对于每个来说, 不需要每次都重置k进行遍历, 只需要接着上一次的继续往后走就行了

class Solution {
    
    
public:
    int triangleNumber(vector<int>& nums) {
    
    
        int len = nums.size();
        if(len<3)
            return 0;

        sort(nums.begin(),nums.end());
        int result = 0;
        
        for(int i=0;i<len-2;i++)
        {
    
    
            int k = i+1;
            for(int j=i+1;j<len-1;j++)
            {
    
    
                int target = nums[i] + nums[j];
                while(k+1<len && nums[k+1]<target)
                    k++;
                result += max(k-j,0);
            }
        }
        return result;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_45972928/article/details/126186575