有效三角形个数
有效三角形的个数
题目描述
给定一个包含非负整数的数组 nums
,返回其中可以组成三角形三条边的三元组个数。
示例 1:
1 | 输入: nums = [2,2,3,4] |
示例 2:
1 | 输入: nums = [4,2,3,4] |
提示:
1 <= nums.length <= 1000
0 <= nums[i] <= 1000
题解一(暴力求解)
ps:此种解法会导致超时。
三层 for 循环枚举出所有的三元组,并且判断是否能构成三⻆形。
判断三⻆形的优化:
▪ 如果能构成三⻆形,需要满⾜任意两边之和要⼤于第三边。但是实际上只需让较⼩的两条边之和⼤于第三边即可。
▪ 因此我们可以先将原数组排序,然后从⼩到⼤枚举三元组,⼀⽅⾯省去枚举的数量,另⼀⽅⾯⽅便判断是否能构成三⻆形。
C++版本
1 | class Solution { |
C版本
1 | int compare(const void *a, const void *b) { |
题解二(排序 + 双指针)
算法思路
先将数组排序。
根据「解法⼀」中的优化思想,我们可以固定⼀个「最⻓边」,然后在⽐这条边⼩的有序数组中找出⼀个⼆元组,使这个⼆元组之和⼤于这个最⻓边。由于数组是有序的,我们可以利⽤「对撞指针」来优化。
设最⻓边枚举到index
位置,区间 [left, right]
是index
位置左边的区间(也就是⽐它(最长边)⼩的区 间):
如果 nums[left] + nums[right] > nums[index]
:
▪ 说明
[left, right - 1]
区间上的所有元素均可以与nums[right]
构成⽐nums[index]
⼤的⼆元组 ,因为区间是有序的,left
向后移动获得的边比此时left
的边要大,恒满足组成三角形。▪ 满⾜条件的有
right - left
种 。▪ 此时
right
位置的元素的所有情况相当于全部考虑完毕,right--
,进⼊下⼀轮判断 。
如果 nums[left] + nums[right] <= nums[index]
:
▪ 说明
left
位置的元素是不可能与[left + 1, right]
位置上的元素构成满⾜条件的⼆元组此时▪
left
位置的元素可以舍去,left++
进⼊下轮循环,因为left
向后移动可能获取更大的边,可能得到满足条件的二元组。
C++版本
1 | class Solution { |