Given an array consists of non-negative integers, your task is to count the number of triplets chosen from the array that can make triangles if we take them as side lengths of a triangle.
Example 1:
Input: [2,2,3,4]
Output: 3
Explanation:
Valid combinations are:
2,3,4 (using the first 2)
2,3,4 (using the second 2)
2,2,3
Note:
The length of the given array won’t exceed 1000.
The integers in the given array are in the range of [0, 1000].
超过100只能用O(N2)复杂度
在数组中找出所有可以组成三角形的组合数
思路:
如果列举所有组合,来判断两边之和是否大于第三边,会出现TLE
所以只能用O(N2)复杂度的算法
可以这样看,先把数组降序或升序排序,比如说升序
把数组最右边也就是最长的边当作c,那么只需要判断c左边的部分中选出的两条边a,b的和是不是大于c
c左边的部分要选出a,b,a<b,那么可以看到如果a+b>c,那么a右边直到b之前的数+b都会>c,因为数组是升序的,a右边的都会大于a
举个例子[2,2,3,4]
c取4,b取c左边的3,a取第一个数2,a+b>c,所以a到b之间的所有边都可以和b,c组成三角形,即a可取第一个和第二个2
那么就转换成了双指针问题,a+b>c,那么它右边直到b之前的个数都是有效组合数,这时可以把b放小,即b所在的指针左移,计算在新的b的条件下有效的三角边个数
同理如果a+b<c, 就需要把a右移,让a更大一些
然后c从大到小遍历即可
注意每次c到一个新的位置,b都要置为c左边的数,a都要重新置0(最小的边)
public int triangleNumber(int[] nums) {
if(nums == null || nums.length < 3) {
return 0;
}
int n = nums.length;
int result = 0;
Arrays.sort(nums);
for(int c = n-1; c > 1; c--) {
int b = c - 1;
int a = 0;
while(b > a) {
if(nums[a] + nums[b] > nums[c]) {
result += (b - a);
b --;
} else {
a ++;
}
}
}
return result;
}