【LeetCode每日一题】——611.有效三角形的个数

文章目录

  • 一【题目类别】
  • 二【题目难度】
  • 三【题目编号】
  • 四【题目描述】
  • 五【题目示例】
  • 六【解题思路】
  • 七【题目提示】
  • 八【时间频度】
  • 九【代码实现】
  • 十【提交结果】

一【题目类别】

  • 二分查找

二【题目难度】

  • 中等

三【题目编号】

  • 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

六【解题思路】

  • 对于如何组成合法三角形,从小学我们就学过了:任意两边之和大于第三边。所以基于这个思路,我们只需要在数组中逐个判断任意两边之和是否大于第三边
  • 找到前两边比较简单,遍历即可,那么如何找到第三边呢?如果也通过遍历去寻找,很明显时间复杂度是 O ( n 3 ) O(n^3) O(n3),为了降低时间复杂度,我们可以使用二分查找来找到第三边,既然使用二分查找,就要首先对数组进行排序
  • 然后需要找到前两边,这个使用 f o r for for循环遍历即可
  • 找第三边的时候使用二分查找,我们只需要将中间值对应的边长和其余两边之和比较,如果中间值对应的边长大于或等于其余两边之和,这显然是不满足的,那么应该继续向左查找,因为左边的值比较小;反之应该向右查找,因为数组现在是有序的,中间值满足要求,那么小于中间值的也都满足要求,记录这个位置,并向右查找是否还有满足要求的值
  • 每次遍历将得到的结果累加记录,需要注意上一步记录位置的变量需要初始化为第二条边的位置,因为最后算个数的时候,没有满足要求的边就不会累加,否则会出错
  • 最后返回结果即可

七【题目提示】

  • 1 < = n u m s . l e n g t h < = 1000 1 <= nums.length <= 1000 1<=nums.length<=1000
  • 0 < = n u m s [ i ] < = 1000 0 <= nums[i] <= 1000 0<=nums[i]<=1000

八【时间频度】

  • 时间复杂度: O ( n 2 l o g n ) O(n^2logn) O(n2logn),其中 n n n为数组的长度
  • 空间复杂度: O ( l o g n ) O(logn) O(logn),其中 n n n为数组的长度

九【代码实现】

  1. Java语言版
class Solution {
    public int triangleNumber(int[] nums) {
        Arrays.sort(nums);
        int len = nums.length;
        int res = 0;
        for(int i = 0;i<len;i++){
            for(int j = i + 1;j<len;j++){
                int left = j + 1;
                int right = len - 1;
                int k = j;
                while(left <= right){
                    int mid = (left + right) / 2;
                    if(nums[mid] >= nums[i] + nums[j]){
                        right = mid - 1;
                    }else{
                        k = mid;
                        left = mid + 1;
                    }
                }
                res += k - j;
            }
        }
        return res;
    }
}
  1. C语言版
int compare(int *a,int *b)
{
    return *a - *b;
}

int triangleNumber(int* nums, int numsSize)
{
    qsort(nums,numsSize,sizeof(int),compare);
    int len = numsSize;
    int res = 0;
    for(int i = 0;i<len;i++)
    {
        for(int j = i + 1;j<len;j++)
        {
            int left = j + 1;
            int right = len - 1;
            int k = j;
            while(left <= right)
            {
                int mid = (left + right) / 2;
                if(nums[mid] >= nums[i] + nums[j])
                {
                    right = mid - 1;
                }
                else
                {
                    k = mid;
                    left = mid + 1;
                }
            }
            res += k - j;
        }
    }
    return res;
}
  1. Python版
class Solution:
    def triangleNumber(self, nums: List[int]) -> int:
        nums.sort()
        n = len(nums)
        res = 0
        for i in range(0,n):
            for j in range(i + 1,n):
                left = j + 1
                right = n - 1
                k = j
                while left <= right:
                    mid = (left + right) // 2
                    if nums[mid] >= nums[i] + nums[j]:
                        right = mid - 1
                    else:
                        k = mid
                        left = mid + 1
                res += k - j
        return res

十【提交结果】

  1. Java语言版
    在这里插入图片描述

  2. C语言版
    在这里插入图片描述

  3. Python语言版
    在这里插入图片描述

你可能感兴趣的:(LeetCode,leetcode,算法,数据结构,二分查找,c语言)