题:https://leetcode.com/problems/valid-triangle-number/
题目大意
从数组中取3个数,使得 这 3 个元素 可以组成 三角形。
思路
由于 抽取的方式 是 C
方法一 a + b > c && abs(a - b) < c
上面 形成 三角形的公式。
对于确定的 a、b,我们只需要确定 c的位置。
对数组排序,按顺序 抽取 a,b ,确定 数组 b 后 满足 上述条件的 c的范围。
这里使用
lower_bound() abs(a - b) < c
upper_bound() a + b> c
若lower_bound() 或 upper_bound() 未找到,upper_bound - lower_bound 可能为负数,需要判断。
class Solution {
public int triangleNumber(int[] nums) {
Arrays.sort(nums);
int res = 0 ;
for(int i = 0 ; i < nums.length ; i ++)
for(int j = i+1 ; j < nums.length ; j++){
int cUpperBound = nums[i] + nums[j];
int cLowerBound = Math.abs(nums[i] - nums[j]);
int l = j+1 , r = nums.length;
while(l < r){
int m = l + ((r - l)>>1);
if(nums[m] > cLowerBound)
r = m;
else
l = m + 1;
}
int startIndex = l;
l = j+1;
r = nums.length;
while(l < r){
int m = l + ((r - l)>>1);
if(nums[m] < cUpperBound)
l = m + 1;
else
r = m;
}
int endIndex = l;
res += endIndex - startIndex >= 0 ? endIndex - startIndex:0;
}
return res;
}
}
方法二 a + b > c && a + c > b && c + b > a
这是另一种 判断 三角形的方法。
对数组排序后,只需要判断 a + b > c,因为 a <=b <= c
所以 只需要 求 upper_bound() a + b> c
class Solution {
public int upper_bound(int[] nums,int l ,int r,int x){
while(l < r){
int m = l + ((r -l)>>1);
if(nums[m] < x)
l = m +1;
else
r = m;
}
return l;
}
public int triangleNumber(int[] nums) {
Arrays.sort(nums);
int res = 0 ;
for(int i = 0 ; i < nums.length ; i ++){
for(int j = i+1 ; j < nums.length ; j++){
int cUpperBound = nums[i] + nums[j];
int k = upper_bound(nums,j+1,nums.length,cUpperBound);
res += k - (j+1);
}
}
return res;
}
}
对于 k 可以 进一步优化。
参考:https://leetcode.com/problems/valid-triangle-number/solution/
class Solution {
public int upper_bound(int[] nums,int l ,int r,int x){
while(l < r){
int m = l + ((r -l)>>1);
if(nums[m] < x)
l = m +1;
else
r = m;
}
return l;
}
public int triangleNumber(int[] nums) {
Arrays.sort(nums);
int res = 0 ;
for(int i = 0 ; i < nums.length-2; i ++){
int k = i + 2;
for(int j = i+1 ; j < nums.length -1 && nums[i] != 0; j++){
int cUpperBound = nums[i] + nums[j];
k = upper_bound(nums,k,nums.length,cUpperBound);
res += k - (j+1);
}
}
return res;
}
}
方法三 线性方法
参考:https://leetcode.com/problems/valid-triangle-number/solution/
class Solution {
public int upper_bound(int[] nums,int l ,int r,int x){
while(l < r){
int m = l + ((r -l)>>1);
if(nums[m] < x)
l = m +1;
else
r = m;
}
return l;
}
public int triangleNumber(int[] nums) {
Arrays.sort(nums);
int res = 0 ;
for(int i = 0 ; i < nums.length-2; i ++){
int k = i + 2;
for(int j = i+1 ; j < nums.length -1 && nums[i] != 0; j++){
int cUpperBound = nums[i] + nums[j];
k = upper_bound(nums,k,nums.length,cUpperBound);
res += k - (j+1);
}
}
return res;
}
}