Skip to content

Commit e48eff5

Browse files
authored
feat: update solutions to lc problem: No.0611 (doocs#4748)
1 parent 8c1d32f commit e48eff5

File tree

7 files changed

+156
-222
lines changed

7 files changed

+156
-222
lines changed

solution/0600-0699/0611.Valid Triangle Number/README.md

Lines changed: 57 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ tags:
2929
<pre>
3030
<strong>输入:</strong> nums = [2,2,3,4]
3131
<strong>输出:</strong> 3
32-
<strong>解释:</strong>有效的组合是:
32+
<strong>解释:</strong>有效的组合是:
3333
2,3,4 (使用第一个 2)
3434
2,3,4 (使用第二个 2)
3535
2,2,3
@@ -58,13 +58,19 @@ tags:
5858

5959
### 方法一:排序 + 二分查找
6060

61-
一个有效三角形需要满足:**任意两边之和大于第三边**。即:`a + b > c`①, `a + c > b`②, `b + c > a`③。
61+
一个有效三角形需要满足:**任意两边之和大于第三边**。即:
6262

63-
如果我们将边按从小到大顺序排列,即 `a < b < c`,那么显然 ②③ 成立,我们只需要确保 ① 也成立,就可以形成一个有效三角形。
63+
$$a + b \gt c \tag{1}$$
6464

65-
我们在 `[0, n - 3]` 范围内枚举 i,在 `[i + 1, n - 2]` 范围内枚举 j,在 `[j + 1, n - 1]` 范围内进行二分查找,找出第一个大于等于 `nums[i] + nums[j]` 的下标 left,那么在 `[j + 1, left - 1]` 范围内的 k 满足条件,将其累加到结果 ans。
65+
$$a + c \gt b \tag{2}$$
6666

67-
时间复杂度:$O(n^2\log n)$。
67+
$$b + c \gt a \tag{3}$$
68+
69+
如果我们将边按从小到大顺序排列,即 $a \leq b \leq c$,那么显然 (2)(3) 成立,我们只需要确保 (1) 也成立,就可以形成一个有效三角形。
70+
71+
我们在 $[0, n - 3]$ 范围内枚举 i,在 $[i + 1, n - 2]$ 范围内枚举 j,在 $[j + 1, n - 1]$ 范围内进行二分查找,找出第一个大于等于 $nums[i] + nums[j]$ 的下标 left,那么在 $[j + 1, left - 1]$ 范围内的 k 满足条件,将其累加到结果 $\textit{ans}$。
72+
73+
时间复杂度 $O(n^2\log n)$,空间复杂度 $O(\log n)$。其中 $n$ 是数组的长度。
6874

6975
<!-- tabs:start -->
7076

@@ -88,20 +94,22 @@ class Solution:
8894
class Solution {
8995
public int triangleNumber(int[] nums) {
9096
Arrays.sort(nums);
91-
int n = nums.length;
92-
int res = 0;
93-
for (int i = n - 1; i >= 2; --i) {
94-
int l = 0, r = i - 1;
95-
while (l < r) {
96-
if (nums[l] + nums[r] > nums[i]) {
97-
res += r - l;
98-
--r;
99-
} else {
100-
++l;
97+
int ans = 0;
98+
for (int i = 0, n = nums.length; i < n - 2; ++i) {
99+
for (int j = i + 1; j < n - 1; ++j) {
100+
int left = j + 1, right = n;
101+
while (left < right) {
102+
int mid = (left + right) >> 1;
103+
if (nums[mid] >= nums[i] + nums[j]) {
104+
right = mid;
105+
} else {
106+
left = mid + 1;
107+
}
101108
}
109+
ans += left - j - 1;
102110
}
103111
}
104-
return res;
112+
return ans;
105113
}
106114
}
107115
```
@@ -112,12 +120,14 @@ class Solution {
112120
class Solution {
113121
public:
114122
int triangleNumber(vector<int>& nums) {
115-
sort(nums.begin(), nums.end());
123+
ranges::sort(nums);
116124
int ans = 0, n = nums.size();
117125
for (int i = 0; i < n - 2; ++i) {
118126
for (int j = i + 1; j < n - 1; ++j) {
119-
int k = lower_bound(nums.begin() + j + 1, nums.end(), nums[i] + nums[j]) - nums.begin() - 1;
120-
ans += k - j;
127+
int sum = nums[i] + nums[j];
128+
auto it = ranges::lower_bound(nums.begin() + j + 1, nums.end(), sum);
129+
int k = int(it - nums.begin()) - 1;
130+
ans += max(0, k - j);
121131
}
122132
}
123133
return ans;
@@ -130,19 +140,15 @@ public:
130140
```go
131141
func triangleNumber(nums []int) int {
132142
sort.Ints(nums)
143+
n := len(nums)
133144
ans := 0
134-
for i, n := 0, len(nums); i < n-2; i++ {
145+
for i := 0; i < n-2; i++ {
135146
for j := i + 1; j < n-1; j++ {
136-
left, right := j+1, n
137-
for left < right {
138-
mid := (left + right) >> 1
139-
if nums[mid] >= nums[i]+nums[j] {
140-
right = mid
141-
} else {
142-
left = mid + 1
143-
}
147+
sum := nums[i] + nums[j]
148+
k := sort.SearchInts(nums[j+1:], sum) + j + 1 - 1
149+
if k > j {
150+
ans += k - j
144151
}
145-
ans += left - j - 1
146152
}
147153
}
148154
return ans
@@ -154,17 +160,14 @@ func triangleNumber(nums []int) int {
154160
```ts
155161
function triangleNumber(nums: number[]): number {
156162
nums.sort((a, b) => a - b);
157-
let n = nums.length;
163+
const n = nums.length;
158164
let ans = 0;
159-
for (let i = n - 1; i >= 2; i--) {
160-
let left = 0,
161-
right = i - 1;
162-
while (left < right) {
163-
if (nums[left] + nums[right] > nums[i]) {
164-
ans += right - left;
165-
right--;
166-
} else {
167-
left++;
165+
for (let i = 0; i < n - 2; i++) {
166+
for (let j = i + 1; j < n - 1; j++) {
167+
const sum = nums[i] + nums[j];
168+
let k = _.sortedIndex(nums, sum, j + 1) - 1;
169+
if (k > j) {
170+
ans += k - j;
168171
}
169172
}
170173
}
@@ -179,56 +182,26 @@ impl Solution {
179182
pub fn triangle_number(mut nums: Vec<i32>) -> i32 {
180183
nums.sort();
181184
let n = nums.len();
182-
let mut res = 0;
183-
for i in (2..n).rev() {
184-
let mut left = 0;
185-
let mut right = i - 1;
186-
while left < right {
187-
if nums[left] + nums[right] > nums[i] {
188-
res += right - left;
189-
right -= 1;
190-
} else {
191-
left += 1;
192-
}
193-
}
194-
}
195-
res as i32
196-
}
197-
}
198-
```
199-
200-
<!-- tabs:end -->
201-
202-
<!-- solution:end -->
203-
204-
<!-- solution:start -->
205-
206-
### 方法二
207-
208-
<!-- tabs:start -->
209-
210-
#### Java
211-
212-
```java
213-
class Solution {
214-
public int triangleNumber(int[] nums) {
215-
Arrays.sort(nums);
216-
int ans = 0;
217-
for (int i = 0, n = nums.length; i < n - 2; ++i) {
218-
for (int j = i + 1; j < n - 1; ++j) {
219-
int left = j + 1, right = n;
220-
while (left < right) {
221-
int mid = (left + right) >> 1;
222-
if (nums[mid] >= nums[i] + nums[j]) {
223-
right = mid;
224-
} else {
185+
let mut ans = 0;
186+
for i in 0..n.saturating_sub(2) {
187+
for j in i + 1..n.saturating_sub(1) {
188+
let sum = nums[i] + nums[j];
189+
let mut left = j + 1;
190+
let mut right = n;
191+
while left < right {
192+
let mid = (left + right) / 2;
193+
if nums[mid] < sum {
225194
left = mid + 1;
195+
} else {
196+
right = mid;
226197
}
227198
}
228-
ans += left - j - 1;
199+
if left > j + 1 {
200+
ans += (left - 1 - j) as i32;
201+
}
229202
}
230203
}
231-
return ans;
204+
ans
232205
}
233206
}
234207
```

0 commit comments

Comments
 (0)