给定一个包含非负整数的数组,你的任务是统计其中可以组成三角形三条边的三元组个数。
示例 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/
解题思路:
- 首先想到的是暴力枚举,但显然时间复杂度会达到O(N³)。
- 可以先将数组排序,在最内层循环利用三角形三边关系(两最短边之和大于最长边),提前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)
难度:中等
标签:数组