力扣--四数之和,三数之和,二数之和--双指针法

二数之和:固定一个数,然后遍历数组寻找另一个数;
三数之和:固定一个数,对另外两个数进行相当于两数之和的寻找操作
四数之和:固定一个数,对另外三个数进行相当于三数之和的操作

四/数之和的代码:

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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值