
我的思路(暴力解)
这个题感觉和前面不太一样了,双指针的变化规律我没有找出来,当判断出三角形之后我发现无论移动左指针,还是移动右指针,三角形都是成立的。一时半会没想到怎么解决,我就直接暴力破解了,直接遍历所有情况,就可以解决问题了。
public int triangleNumber(int[] nums) {
Arrays.sort(nums);
int n = nums.length;
int ans=0;
for(int i = 0;i<n-2;i++){
int x = nums[i];
for(int j = i+1;j<n-1;j++){
int k = n-1;
while(j<k){
int y = nums[i]+nums[j]-nums[k];
if(y>0){
ans++;
}
k--;
}
}
}
return ans;
}
优化方案,我发现这个ans不用每次都进行++,可以直接统计出来所有满足的。
while(j<k){
int y = nums[i] + nums[j] - nums[k];
if (y > 0) {
int len = k-j;
ans+=len;
break;
}
k--;
}
灵神思路
灵神就是强,当我还再纠结这个无法判断双指针移动方向的时候,灵神已经是另一个境界了,他并不是类似于传统的枚举最短的那一个,而是换了一种思路,枚举最长的。让最外层从i=2开始,然后让j和k是i的左边的边。
此时双指针就很容易的判断出移动方向了
当左边两个短边的和 nums[j]+nums[k]大于 最外层的nums[i]的时候,三角形成立,此时从i到j,都是满足条件的三角形(我们不用对j进行++了),我们将其加入结果ans += j - i;,然后k--
当左边两个短边的和小于等于最外层的时候,三角形不成立,我们要扩大短边的话,直接j++
class Solution {
public int triangleNumber(int[] nums) {
Arrays.sort(nums);
int ans = 0;
for (int k = 2; k < nums.length; k++) {
int c = nums[k];
int i = 0; // a=nums[i]
int j = k - 1; // b=nums[j]
while (i < j) {
if (nums[i] + nums[j] > c) {
// 由于 nums 已经从小到大排序
// nums[i]+nums[j] > c 同时意味着:
// nums[i+1]+nums[j] > c
// nums[i+2]+nums[j] > c
// ...
// nums[j-1]+nums[j] > c
// 从 i 到 j-1 一共 j-i 个
ans += j - i;
j--;
} else {
// 由于 nums 已经从小到大排序
// nums[i]+nums[j] <= c 同时意味着
// nums[i]+nums[j-1] <= c
// ...
// nums[i]+nums[i+1] <= c
// 所以在后续的内层循环中,nums[i] 不可能作为三角形的边长,没有用了
i++;
}
}
}
return ans;
}
}
作者:灵茶山艾府
链接:https://leetcode.cn/problems/valid-triangle-number/solutions/2432875/zhuan-huan-cheng-abcyong-xiang-xiang-shu-1ex3/
来源:力扣(LeetCode)
1084

被折叠的 条评论
为什么被折叠?



