leecode611 有效三角形的个数
我的思路(暴力解)
这个题感觉和前面不太一样了,双指针的变化规律我没有找出来,当判断出三角形之后我发现无论移动左指针,还是移动右指针,三角形都是成立的。一时半会没想到怎么解决,我就直接暴力破解了,直接遍历所有情况,就可以解决问题了。
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)