LeetCode打卡:611. 有效三角形的个数

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

示例 1:

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

链接:https://leetcode.com/problems/valid-triangle-number/submissions/
解题思路:

  1. 首先想到的是暴力枚举,但显然时间复杂度会达到O(N³)。
  2. 可以先将数组排序,在最内层循环利用三角形三边关系(两最短边之和大于最长边),提前break。

下面是我的解法:
法一:二分查找,可以将暴力枚举的最内层循环改为二分查找,将时间复杂度将为O(N²logN).

class Solution(object):
    def triangleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        # 二分查找
        l = len(nums)
        if l < 3:
            return 0
        res = 0
        nums.sort()
        for i in range(l - 2):
            if nums[i] <= 0:
                continue
            for j in range(i + 1, l - 1):
                k = self.binarySearch(j + 1, l - 1, nums, nums[i] + nums[j])
                res += k - j - 1
        return res
    
    # 找到第一个不小于目标数的位置
    def binarySearch(self, l, r, arr, target):
        if arr[-1] < target:
            return len(arr)
        while l < r:
            mid = (l + r)//2 
            # 每定位到一个小于target的数,就取右半边
            if arr[mid] < target:
                l = mid + 1
            else:
                r = mid
        return r

法二:双指针法,解法同:167. 两数之和 II - 输入有序数组

class Solution(object):
    def triangleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        # 双指针法
        l = len(nums)
        if l < 3:
            return 0
        res = 0
        nums.sort()
        for i in range(l):
            k = i + 1
            r = l - 1
            while k < r:
                if nums[i] + nums[k] > nums[r]:
                    res += 1
                    r -= 1
                else:
                    k += 1
        return res

Time: O(N²)
Space:O(1)
难度:中等
标签:数组

你可能感兴趣的:(LeetCode打卡,leetcode,算法,数据结构)