T18. 4Sum【Medium】
题目
给一个有 n 个整数的数组 S,找到 S 中的所有和为 target 的四元组(S 中元素 a,b,c,d 使得 a+b+c+d = target )。找到所有数组中所有符合要求的四元组。
注释: 解答中不能有重复的四元组
例如, 给出数组 S = [1, 0, -1, 0, -2, 2],以及 target = 0.
一个解集是:
[
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]
思路
① 思路和前面的题很像,在补充里我会放出链接
② 主要要注意的是搜索方式以及去重
③ 下面代码的搜索方式是前两个数用两个嵌套的 for 循环依次匹配,后两个数是在第二个数后面的数段中从头和尾分别向中间靠拢,由于排好序了,所以偏大时,第三个数往右选,偏小时第四个数往左选
④ 去重的话通过 while 循环在四个数用到的时候分别判断并且去重,可以看代码,我有标注
代码
代码取自 Top Solution,稍作注释
public List<List<Integer>> fourSum(int[] num, int target) {
ArrayList<List<Integer>> ans = new ArrayList<>();
//当小于4时不存在,所以直接返回
if(num.length<4)return ans;
//排序
Arrays.sort(num);
for(int i=0; i<num.length-3; i++){
//去掉重复的数字
if(i>0&&num[i]==num[i-1])continue;
for(int j=i+1; j<num.length-2; j++){
//去掉重复的数字
if(j>i+1&&num[j]==num[j-1])continue;
//剩下low和high两个数字在后面网中间夹
int low=j+1, high=num.length-1;
while(low<high){
int sum=num[i]+num[j]+num[low]+num[high];
if(sum==target){
//相等时加入数组
ans.add(Arrays.asList(num[i], num[j], num[low], num[high]));
//这两个while也是去重
while(low<high&&num[low]==num[low+1])low++;
while(low<high&&num[high]==num[high-1])high--;
low++;
high--;
}
//由于排好序了,所以偏大时,第三个数往右选,偏小时第四个数往左选
else if(sum<target)low++;
else high--;
}
}
}
return ans;
}
补充
leetcode 的第十五题和第十六题的题目代码思想和这个很相近,可以看一下~