二数之和:固定一个数,然后遍历数组寻找另一个数;
三数之和:固定一个数,对另外两个数进行相当于两数之和的寻找操作
四数之和:固定一个数,对另外三个数进行相当于三数之和的操作
四/数之和的代码:
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> result=new ArrayList<List<Integer>>();
Arrays.sort(nums);
int length=nums.length;
for(int i=0;i<length;i++){
int j=i+1;
if(i==0||nums[i]!=nums[i-1])
while(j<length){
int l=j+1;//左指针
int r=length-1;//右指针
while(l<r){
int sum=nums[i]+nums[j]+nums[l]+nums[r];//获得当前和
if(sum>target){//大于目标值,则右指针朝较小方向移动
while(nums[r]==nums[r-1])r--;//除重
r--;
}
else if(sum<target){//小于目标值,左指针向较大方向移动
while(++l<length&&nums[l]==nums[l-1]);//除重
}
else if(sum==target){//得到目标解,插入链表
List<Integer> list=new ArrayList<Integer>();
list.add(nums[i]);
list.add(nums[j]);
list.add(nums[l]);
list.add(nums[r]);
result.add(list);
while(++l<length&&nums[l]==nums[l-1]);//除重
while(--r>0&&nums[r]==nums[r+1]);
}
}
while(++j<length&&nums[j]==nums[j-1]);//除重
}
}
return result;
}
}
上述代码对于双指针的方法有了较好的实现,但是对于本题,我们可以通过判断当前解是否可行来进行是否进行下面计算的方法来大大减少计算
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> result=new ArrayList<List<Integer>>();
Arrays.sort(nums);
int length=nums.length;
for(int i=0;i<length;i++){
int j=i+1;
if(i==0||nums[i]!=nums[i-1])
while(j<length){
int l=j+1;
int r=length-1;
while(l<r){
int sum1=nums[i]+nums[j]+nums[l]+nums[l+1];//获得当前状态最小值
int sum2=nums[i]+nums[j]+nums[r-1]+nums[r];//获得当前状态最大值
int sum=nums[i]+nums[j]+nums[l]+nums[r];
if(sum1>target||sum2<target)//当最小值大于目标值,最大值小于目标值时为不可解状态,不需要进行下面的计算。
break;
if(sum>target){
while(nums[r]==nums[r-1])r--;
r--;
}
else if(sum<target){
while(++l<length&&nums[l]==nums[l-1]);
}
else if(sum==target){
List<Integer> list=new ArrayList<Integer>();
list.add(nums[i]);
list.add(nums[j]);
list.add(nums[l]);
list.add(nums[r]);
result.add(list);
while(++l<length&&nums[l]==nums[l-1]);
while(--r>0&&nums[r]==nums[r+1]);
}
}
while(++j<length&&nums[j]==nums[j-1]);
}
}
return result;
}
}