题目描述
给定一个包含非负整数的数组 nums,返回其中可以组成三角形三条边的三元组个数。
示例 1:
输入:[2,2,3,4]
输出:3
解释:有效的组合是:(2,3,4), (2,3,4), (2,2,3)
示例 2:
输入:[4,2,3,4]
输出:4
提示:
1 <= nums.length <= 10000 <= nums[i] <= 1000
算法思路
三角形只需要看最短两条边和最长边的关系。数组排好序以后,假设 a <= b <= c,只要 a + b > c,这个三元组就成立。其他两个不等式在排序后天然满足,所以没必要反复检查。
这里比较顺手的做法是固定最长边 c,再用双指针去找剩下两条边。排序后从右往左枚举 i,把 nums[i] 当作最长边,left 放在最左边,right 放在 i - 1。
如果 nums[left] + nums[right] > nums[i],说明 left 到 right - 1 这些位置上的数,和 nums[right] 配对后都能满足条件。这个时候不用一个个试,直接把数量 right - left 加进去,然后 right-- 继续收缩。反过来,如果和不够大,说明 nums[left] 太小了,往右挪一个更合适。
这种写法比三层循环干净得多,复杂度也压到了 O(N^2)。排序占的额外空间一般按 O(log N) 计,主要来自实现里的递归栈。

代码实现
import java.util.Arrays;
class Solution {
public int triangleNumber(int[] nums) {
Arrays.sort(nums);
int count = 0;
nums.length;
( n - ; i >= ; i--) {
;
i - ;
(left < right) {
(nums[left] + nums[right] > nums[i]) {
count += right - left;
right--;
} {
left++;
}
}
}
count;
}
}



