如题

最直接的方法一定是禁忌之三重循环了,那么很显然的做法就是双指针优化它了
public static List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
if(nums==null||nums.length<3) {
return result;
}
Arrays.sort(nums); //排序
for(int i=0;i<nums.length-2;i++) {
int num =nums[i]; //最小值
if(num+nums[i+1]+nums[i+2]>0) {
break; //最小值大于0则后续肯定不存在
}
if(i>0&&nums[i]==nums[i-1]||nums[i]+nums[nums.length-1]+nums[nums.length-2]<0) {
continue; //相同及最大值判断
}
int m =i+1;
int n =nums.length-1;
while(m!=n) {
if(num+nums[m]+nums[n]<0||(m>i+1&&nums[m]==nums[m-1])) { //小于目标值则增大m
m++; //注意判断m处元素若等于前值,则跳过
}else {
if((num+nums[m]+nums[n]>0||n<nums.length-1&&nums[n]==nums[n+1])) {
n--; //同样的,大于目标值则减小n,对应的需要判断n处元素是否大于后值
}else {
List<Integer> lis = new ArrayList<Integer>();
lis.add(num);
lis.add(nums[m]);
lis.add(nums[n]);
result.add(lis);
n--;
}
}
}
}
return result;
}
需要注意去重和剪枝

写法上可以有小得优化,在符合情况时是可以直接m++同时n–,对应的需要注意退出条件需要变为m<n。暴力的也来一个
public static List<List<Integer>> threeSum1(int[] nums) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
if(nums==null||nums.length<3) {
return result;
}
Arrays.sort(nums);
for(int i=0;i<nums.length-2;i++) {
if(nums[i]>0) {
break;
}
if(i>0&&nums[i]==nums[i-1]) {
continue;
}
for(int m=i+1;m<nums.length-1;m++) {
if(m>i+1&&nums[m]==nums[m-1]) {
continue;
}
for(int n=m+1;n<nums.length;n++) {
if(n>m+1&&nums[n]==nums[n-1]) {
continue;
}
if(nums[i]+nums[m]+nums[n]==0) {
List<Integer> lis = new ArrayList<Integer>();
lis.add(nums[i]);
lis.add(nums[m]);
lis.add(nums[n]);
result.add(lis);
}
}
}
}
return result;
}
就不测了肯定不好看
本文深入探讨了解决三数之和问题的高效算法。通过使用双指针技巧优化三重循环,显著提高了查找三个数相加为零的组合的速度。文章详细解释了排序、去重和剪枝等关键步骤,提供了清晰的代码实现。
756

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



