leetcode每日一题题解—— 611. 有效三角形的个数——2021年8月4日

611. 有效三角形的个数

Title Description

Given an integer array nums, return the number of triplets chosen from the array that can make triangles if we take them as side lengths of a triangle.

Example 1:

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

Example 2:

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

Constraints:

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

题目描述

给定一个包含非负整数的数组,你的任务是统计其中可以组成三角形三条边的三元组个数。

示例 1:

输入: [2,2,3,4]
输出: 3
解释:
有效的组合是: 
2,3,4 (使用第一个 2)
2,3,4 (使用第二个 2)
2,2,3

注意:

数组长度不超过1000。
数组里整数的范围为 [0, 1000]。

解题思路1

排序 + 双指针

  • 我们使用一重循环枚举 i。当 i 固定时,我们使用双指针同时维护 j 和 k,它们的初始值均为 i;

  • 我们每一次将 j 向右移动一个位置,即 j←j+1,并尝试不断向右移动 k,使得 k 是最大的满足nums[k]

代码

class Solution {
public:
    int triangleNumber(vector& nums) {

        sort(nums.begin(),nums.end());
        
        int ans=0;

        for(int i=2;i

解题思路2

排序 + 二分查找

  1. 先排序,再二分查找
  2. 查找时,先固定前两个数,然后查第三个数,如果前两个数是a和b,且a<=b,那么第三个数的范围就是:【b,a+b-1】.
  3. 用二分法,在nums剩下范围内寻找:大于等于lower的最小值,以及小于等于upper的最大值。
  4. 由于二分法特性,在向右查找小于等于upper的最大值时,可能找到的是大于upper的第一个值,最后要比较一下确认是否左退一步。

代码

class Solution {
    public int triangleNumber(int[] nums) {
        int n = nums.length;
        if(n<3) return 0;
        Arrays.sort(nums);
        int ans = 0;
        for(int i = 0; i=sum2)continue;
                int lower = nums[j+1];
                int upper = sum2-1;
                // 在:j+1~n-1 之间寻找大于等于lower的最小值,返回坐标。
                int minId = searchMin(nums, j+1, n-1, lower);
                // 在:j+1~n-1 之间寻找小于等于upper的最大值,返回坐标。
                int maxId = searchMax(nums, j+1, n-1, upper);
               // System.out.println("i="+i+",j="+j+", lower="+lower+", upper="+upper+",minId="+minId+", maxId="+maxId);
                ans+=1 + maxId - minId;
            }
        }
        return ans;
    }
    int searchMin(int[] nums, int left, int right, int target){
        while(left>>1;
            if(nums[m]>=target) right=m;
            else left=m+1;
        }
        return left;
    }
    int searchMax(int[] nums, int left, int right, int target){
        while(left>>1;
            if(nums[m]<=target) left=m+1;
            else right=m;
        }
        if(nums[left]>target)return left-1;
        return left;
    }
}


你可能感兴趣的:(二分法,算法,leetcode,数据结构,java)