Poison

611. Valid Triangle Number

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
class Solution {
public int triangleNumber(int[] nums) {
Arrays.sort(nums);

int count = 0;
for (int i = 0; i < nums.length - 2; i++) {
for (int j = i + 1; j < nums.length - 1; j++) {
int sum = nums[i] + nums[j];
// 使用二分搜索查找小于 sum 的最大元素,即寻找右边界
int left = j + 1, right = nums.length;
while (left < right) {
int mid = (left + right) >>> 1;
if (nums[mid] < sum) {
left = mid + 1; // 尝试向右侧逼近
} else if (nums[mid] > sum) {
right = mid;
} else {
right = mid; // 等于 sum 时不合法,向左侧逼近
}
}

// 跳出时 left = right, 且 left 已经不满足条件,所以只能取 left - 1
if (left != j + 1) {
count += (left - 1) - (j + 1) + 1;
}
}
}

return count;
}
}
Two Pointers
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public int triangleNumber(int[] nums) {
Arrays.sort(nums);

int count = 0;
for (int k = nums.length - 1; k >= 2; k--) {
int i = 0, j = k - 1;
while (i < j) {
if (nums[i] + nums[j] > nums[k]) {
// nums[i], nums[i + 1] ... nums[j - 1] 都满足条件
count += j - i;
j--; // 固定 nums[j] 的已经统计完毕
} else {
// 此时和小于等于 nums[k], 只能增加最小边的值
i++;
}
}
}

return count;
}
}
Reference

611. Valid Triangle Number