【LeetCode】611. Number of valid triangles

topic

Given an array nums containing non-negative integers, return the number of triples that can form three sides of a triangle.

Example 1:

Input: nums = [2,2,3,4]
Output: 3
Explanation: Valid combinations are:
2,3,4 (use the first 2)
2,3,4 (use the second 2)
2,2 ,3

Example 2:

Input: nums = [4,2,3,4]
Output: 4

hint:

1 <= nums.length <= 1000
0 <= nums[i] <= 1000

answer

Sorting + Binary Search
The triangle must satisfy a+b>c; a+c>b; b+c>a.
After sorting, a+c>b and b+c>a must be satisfied, just look for 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;
    }
};

Sorting + double pointers
are violent optimizations.
The violent method is three loops, resetting k each time and looping.
But in the sorted sequence, because it is increasing, a+b is also increasing, that is to say, for each For example, you don’t need to reset k every time to traverse, you just need to continue going backwards from the last time.

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;
    }
};

Guess you like

Origin blog.csdn.net/qq_45972928/article/details/126186575