有效三角形个数与和为s的两个数字

📅 发布时间:2026/10/3 6:20:04
有效三角形个数与和为s的两个数字
五、有效三角形的个数给定一个包含非负整数的数组nums返回其中可以组成三角形三条边的三元组个数。示例题目要求返回所有数组中可以组成有效三角形的元素组合。最简单的解法就是暴力枚举列出所有组合记录下可以组成三角形的三元组个数。示例一的解析给出两次相同组合说明虽然两个元素值一样但是下标不一样也可以算作一组。直接套三层循环暴力过掉。代码:class Solution { public int triangleNumber(int[] nums) { int count0; for(int a0;anums.length;a){ for(int b1;bnums.length;b){ for(int c2;cnums.length;c){ while(ba){ b; } while(cb){ c; } if(cnums.length){ break; } if((nums[a]nums[b])nums[c]){ if ((nums[a]nums[c])nums[b]){ if ((nums[b]nums[c])nums[a]){ count; } } } } } } return count; } }但是肯定报错时间复杂度起步 O(n³) 必然超时。需要想一个更优解法。题目说明所有的用例都是非负整数那就可以给数组先排序再进行遍历。乱序数组很难找出规律而且最主要的原因在于不能移动因为保证不了移动后的整数大小。这里用一组暴力解法报错的例子找更优解。刚才说了乱序数组无法向不确定大小的位置移动寻找有效三角形所以先让数组排序。此时再基于三层循环的思路做优化。让三个指针分别指向数组左右侧如果写过盛水最多的容器题目那应该能想到用指针优化这题。我们固定 a 让 b 移动会发现两种情况。若是最小的数加上这个区间里最大的数依旧小于等于 C 那么 a 要向右移。反之这个区间里的数都不用算了全是有效三角形。完成一次循环后C 的位置向左移一格继续寻找有效三角形直到 C 移到2的位置。优化后的代码class Solution { public int triangleNumber(int[] nums) { int count0; Arrays.sort(nums); for(int inums.length-1;i2;i--){ int left0,righti-1; while(leftright){ if(nums[left]nums[right]nums[i]){ countright-left; right--; }else{ left; } } } return count; } }六、和为s的两个数字购物车内的商品价格按照升序记录于数组price。请在购物车中找到两个商品的价格总和刚好是target。若存在多种情况返回任一结果即可。这是一道简单题暴力解法依旧两层循环枚举同时肯定超时。代码class Solution { public int[] twoSum(int[] price, int target) { int[] arr{-1,-1}; for(int i0;iprice.length;i){ for(int j1;jprice.length;j){ if((price[i]price[j])target price[i]!price[j]){ arr[0]price[i]; arr[1]price[j]; } } } return arr; } }优化解法依旧采用双指针。由于数组升序排列降低了很多难度所以不用考虑这么多直接把指针放在左右两侧。等到和为 target 把这两个整数放到一个新数组里返回。代码class Solution { public int[] twoSum(int[] price, int target) { int left0,rightprice.length-1; while(leftright){ int sumprice[left]price[right]; if(sumtarget){ return new int[] {price[left],price[right]}; }else if(sumtarget){ right--; }else{ left; } } return new int[]{0}; } }注意一下如果返回值写在循环体里外边一定要再给一个返回值否则编译器会认为可能没有返回值从而报错。