lc.611.有效三角形的个数
给定一个包含非负整数的数组 nums ,返回其中可以组成三角形三条边的三元组个数。
示例 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
2
|
1 <= nums.length <= 1000
0 <= nums[i] <= 1000
|
解题思路
判断三条边能组成三角形的条件为:
- 任意两边之和大于第三边,任意两边之差小于第三边。
- 三条边长从小到大为 a、b、c,当且仅当 a + b > c 这三条边能组成三角形。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
class Solution {
public:
bool ok(int a,int b,int c) {
return (a+b)>c && (c-b) < a;
}
int triangleNumber(vector<int>& nums) {
int n = nums.size();
if(n<=2) return 0;
sort(nums.begin(),nums.end());
int count = 0;
for(int i=n-1;i>=0;i--) {
int c = nums[i];
int l = 0,r = i-1;
while(l<r) {
int a = nums[l],b = nums[r];
if(a+b > c) {
count += r-l;
--r;
}else {
//<=
l++;
}
}
}
return count;
}
};
|
二分法
从后往前找, 最后一个 $nums[mid] > b+c $的数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
class Solution {
public:
bool ok(int a,int b,int c) {
return (a+b)>c && (c-b) < a;
}
int triangleNumber(vector<int>& nums) {
int n = nums.size();
if(n<=2) return 0;
sort(nums.begin(),nums.end());
int count = 0;
for(int i=0;i<n;i++) {
for(int j=i-1;j>=0;j--) {
int b = nums[j],c = nums[i];
int a;
int mid;
int l= 0,r = j-1;
while(l<r) {
mid = (l+r)/2;
a = nums[mid];
if(a+b>c) {
r = mid;
}else if(a+b==c) {
l = mid+1;
}else {
//<c
l = mid+1;
}
}
if(l==r && nums[r]+nums[j] > nums[i]) {
count += j-r;
}
}
}
return count;
}
};
|