0611. 有效三角形的个数
大约 2 分钟
0611. 有效三角形的个数
- 标签:贪心、数组、双指针、二分查找、排序
- 难度:中等
题目链接
题目大意
描述:给定一个包含非负整数的数组 ,其中 表示第 条边的边长。
要求:统计数组中可以组成三角形三条边的三元组个数。
说明:
- 。
- 。
示例:
- 示例 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
解题思路
思路 1:对撞指针
构成三角形的条件为:任意两边和大于第三边,或者任意两边差小于第三边。只要满足这两个条件之一就可以构成三角形。以任意两边和大于第三边为例,如果用 、、 来表示的话,应该同时满足 、、。如果我们将三条边升序排序,假设 ,则如果满足 ,则 和 一定成立。
所以我们可以先对 进行排序。然后固定最大边 ,利用对撞指针 、 查找较小的两条边。然后判断是否构成三角形并统计三元组个数。
为了避免重复计算和漏解,要严格保证三条边的序号关系为:。具体做法如下:
- 对数组从小到大排序,使用 记录三元组个数。
- 从 开始遍历数组的每一条边, 作为最大边。
- 使用双指针 、。 指向 , 指向 。
- 如果 ,说明第一条边太短了,可以增加第一条边长度,所以将 右移,即
left += 1
。 - 如果 ,说明可以构成三角形,并且第二条边固定为 边的话,第一条边可以在 中任意选择。所以三元组个数要加上 。即
ans += (right - left)
。
- 如果 ,说明第一条边太短了,可以增加第一条边长度,所以将 右移,即
- 直到 跳出循环,输出三元组个数 。
思路 1:代码
class Solution:
def triangleNumber(self, nums: List[int]) -> int:
nums.sort()
size = len(nums)
ans = 0
for i in range(2, size):
left = 0
right = i - 1
while left < right:
if nums[left] + nums[right] <= nums[i]:
left += 1
else:
ans += (right - left)
right -= 1
return ans
思路 1:复杂度分析
- 时间复杂度:,其中 为数组中的元素个数。
- 空间复杂度:,排序需要 的栈空间。