(一、排序+双指针)
这道题跟之前第15题有点类似,还是可以使用排序加双指针来做的。我们先将数组进行排序,然后定义两个for循环,第一层for循环控制第一个数,第二个for循环控制第二个数;然后定义双指针,左指针控制第三个数,右指针控制第四个数,分情况控制其四个数的取值范围,定义List集合,将所有的情况添加至list集合中。
代码:
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> list=new ArrayList<List<Integer>>();//定义List集合来储存答案
Arrays.sort(nums);//将数组进行排序
int n=nums.length;//定义n为数组长度
for(int a=0;a<n-3;a++){//第一重for循环,a代表第一个数,其取值为[0,n-4]
if(a>0 && nums[a]==nums[a-1]){//保证第一个数在下一次判断时不被重复
continue;
}
for(int b=a+1;b<n-2;b++){//第二重for循环,b代表第二个数,其取值为[a+1,n-3]
if (b>a+1 && nums[b]==nums[b-1]){//保证第二个数在下一次判断时不被重复
continue;
}
int c=b+1;//定义左指针,代表第三个数
int d=n-1;//定义右指针,代表第四个数
while(c<d){//保证两指针不相遇
int num=nums[a]+nums[b]+nums[c]+nums[d];//定义num为四数之和
if(num>target){//当num大于目标值时
d--;//将右指针向左移
while(c<d && nums[d]==nums[d+1]){//保证第三个数在下一次判断时不被重复
d--;//如果重复且两指针还没相遇时将右指针向左移
}
}
if (num<target){//当num小于目标值时
c++;//将左指针向右移
while(c<d && nums[c]==nums[c-1]){//保证第四个数在下一次判断时不被重复
c++;//如果重复且两指针还没相遇时将左指针向右移
}
}
if (c==d){//当两指针相遇时,结束while循环
break;
}
if(num==target)//当num值与目标值target相等时
{
List l=new ArrayList();//定义l集合用来储存四个数
l.add(nums[a]);
l.add(nums[b]);
l.add(nums[c]);
l.add(nums[d]);
if(!list.contains(l)){//判断list集合中是否含有重复的l元素(这时l为list中的元素)
list.add(l);//如果没有将l添加进list集合中
}
c++;//将左指针向右移
continue;
}
}
}
}
return list;
}
}