Leetcode18:4Sum
题目描述:4Sum
简而言之,找出数组中和为指定值的四个数,且不能有重复。
双指针
解题过程
其实此题之前还有三数和,与指定值最相近的三数和,这两题大同小异。这一四数和,其实也差不多,有了前面题目的铺垫,第一想法就是用双指针的方法。
自己的想法是,设定了两个双指针,初始为l1=0,r1=nums.length-1; l2=l1+1,r2=r1-1;然后先进行内部双指针的循环,再进行外部双指针的循环。
由于不能重复,所以在内外两个循环时,都要考虑到去重。又因为是四数之和,所以可以在l1和r1之间少于四个数时,提前终止循环。
List<List<Integer>>res=new ArrayList<>();
if (nums.length<4)return res;
int l1=0,r1=nums.length-1;
int l2=l1+1,r2=r1-1;
Arrays.sort(nums);
for (l1=0;l1<nums.length;l1++){
for (r1=nums.length-1;r1>=0;r1--){
l2=l1+1;
r2=r1-1;
while (l2<r2){
int temp=nums[l1]+nums[l2]+nums[r1]+nums[r2];
if (temp==target){
res.add(Arrays.asList(nums[l1],nums[l2],nums[r1],nums[r2]));
while (l2<r2&&nums[l2]==nums[l2+1])l2++;
while (l2<r2&&nums[r2]==nums[r2-1])r2--;
l2++;
r2--;
}
else if(temp<target){
l2++;
}
else if (temp>target){
r2--;
}
}
while (r1-l1>=3&&nums[r1]==nums[r1-1])r1--;
if (r1-l1<3)break;
}
while (nums.length-1-l1>=3&&nums[l1]==nums[l1+1])l1++;
if (nums.length-1-l1<3)break;
}
return res;
看题解时,发现,其实外部不一定要一头一尾使用双指针,直接固定最前面的两个数,再对后面剩下的数使用双指针即可,想法以及实现都会更加简单直接一点。外部头尾指针是完全没有必要的。