题目:力扣https://leetcode-cn.com/problems/4sum/
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> ans = new ArrayList<>();
Arrays.sort(nums);
int l;
int r;
for(int index1=0;index1<nums.length-3;index1++){
if(index1!=0&&nums[index1]==nums[index1-1]){
continue;
}
for(int index2=index1+1;index2<nums.length-2;index2++){
if(index2!=index1+1&&nums[index2]==nums[index2-1]){
continue;
}
l = index2+1;
r = nums.length-1;
while(l<r){
if(nums[index1]+nums[index2]+nums[l]+nums[r]==target){
List<Integer> list = new ArrayList<>();
list.add(nums[index1]);
list.add(nums[index2]);
list.add(nums[l]);
list.add(nums[r]);
ans.add(list);
while(l<r&&nums[l]==nums[l+1]) l++;
while(l<r&&nums[r]==nums[r-1]) r--;
l++;
r--;
}else{
if(nums[index1]+nums[index2]+nums[l]+nums[r]>target){
r--;
}else{
l++;
}
}
}
}
}
return ans;
}
}
思路:这题和leetcode15.三数之和非常相似,这里的思路和三数之和那题的思路也是大同小异。三数之和的思路是先排序,枚举第一个数,然后用双指针法找符合题目要求的两个元素;而这里也是先排序,接着分别枚举前两个元素,然后再用双指针法如法炮制的寻找符合题目要求的两个元素。
1.声明List类型的变量ans,这个就是需要返回的元素;通过Array.sotr()的方法对nums[]数组进行排序操作;分别声明l和r,它们两分别为左指针和右指针。
List<List<Integer>> ans = new ArrayList<>();
Arrays.sort(nums);
int l;
int r;
2.index1是枚举的第一个元素,index2是枚举的第二个元素。为了避免枚举同样的元素导致重复解,因此需要判断当索引所指的元素的值是否与上一个索引所指的元素的值一致,若一致则需要跳开。index也需要进行上述判断重复的操作。然后分别对左指针l与右指针r赋值,左指针初始值应为枚举的第二个元素的下一个元素,而右指针的初始值应为该数组的最后一个元素。
for(int index1=0;index1<nums.length-3;index1++){
if(index1!=0&&nums[index1]==nums[index1-1]){
continue;
}
for(int index2=index1+1;index2<nums.length-2;index2++){
if(index2!=index1+1&&nums[index2]==nums[index2-1]){
continue;
}
l = index2+1;
r = nums.length-1;
//......
}
}
3.若四数之和的值等于target则将这四个元素的值存入list中,然后再将list存入ans中,然后同时将左指针右移和右指针左移(若指针指向的元素的值与上一个指向元素的值相同,则再移动该指针,避免指向重复值导致重复解)。若四数之和的值不等于target,则需要判断四数之和大于还是小于target。若四数之和大于target,则将右指针左移;若四数之和小于target,则将左指针右移。直至移动到左右指针重合,则结束。
while(l<r){
if(nums[index1]+nums[index2]+nums[l]+nums[r]==target){
List<Integer> list = new ArrayList<>();
list.add(nums[index1]);
list.add(nums[index2]);
list.add(nums[l]);
list.add(nums[r]);
ans.add(list);
while(l<r&&nums[l]==nums[l+1]) l++;
while(l<r&&nums[r]==nums[r-1]) r--;
l++;
r--;
}else{
if(nums[index1]+nums[index2]+nums[l]+nums[r]>target){
r--;
}else{
l++;
}
}
}
4.完成上述循环之后,ans已经存好题目所需的答案,返回即可。
return ans;