由于提前做过了4 sum问题,3sum就很明显了
题目
给出一个有n个元素的数组S,S中是否有元素a,b,c满足a+b+c=0?找出数组S中所有满足条件的三元组。
注意:
三元组(a、b、c、d)中的元素必须按非降序排列。(即a≤b≤c)
解集中不能包含重复的三元组。
例如,给定的数组 S = {-1 0 1 2 -1 -4},↵↵ 解集为:↵ (-1, 0, 1)↵ (-1, -1, 2)
题目解析
同样是获得所有的组合,找到符合3个元素相加等于0的组合。
解题思路
- 首先进行排序
- 其次,外层循环控制一个元素移动
- 然后,通过双指针收缩,获取不同的组合进行判断
实例代码
public ArrayList<ArrayList<Integer>> threeSum(int[] num) {
//数字组合必须排序
Arrays.sort(num);
ArrayList<ArrayList<Integer>> lists=new ArrayList<>();
//i循环向右
for (int i=0;i<num.length-2;i++)
{
//第一次控制i重复,也就是第一个元素重复场景
//如果重复跳出本次循环
if (i > 0 && num[i] == num[i - 1]) {
continue;
}
//begin位置为j后边,end为最后一个元素
int begin=i+1,end=num.length-1;
//对begin,end双指针进行收缩
while (begin<end) {
//大于给定值 end--
if (num[i] + num[begin] + num[end] > 0)
end--;
//小于给定值begin++
else if (num[i] + num[begin] + num[end] < 0)
begin++;
//等于给定值,就进行添加
else if (num[i] + num[begin] + num[end] == 0) { //需要在这里进行初始化,否则进行元素覆盖
ArrayList<Integer> list = new ArrayList<>();
list.add(num[i]);
//此组合符合,同时begin,end继续收缩
list.add(num[begin++]);
list.add(num[end--]);
lists.add(list);
//第二次去重,将begin相同的去除
while (begin < end && num[begin -1] == num[begin]) {
begin++;
}
//第三次去重,将end重复去掉
while (begin < end && num[end +1] == num[end]) {
end--;
}
}
}
}
return lists;
}
重要的就是对元素进行去重操作,去重操作应发生在每一层循环。
在我的算法栏目中含有类似题目及解法。
题目来源牛客网。