四数之和-Java-LeetCode第18题

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

  • 0 <= a, b, c, d < n
  • abcd 互不相同
  • nums[a] + nums[b] + nums[c] + nums[d] == target

你可以按 任意顺序 返回答案 。

 

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> ans=new ArrayList<List<Integer>>();
        int n=nums.length;
        Arrays.sort(nums);
        if(n<4){
            return ans;
        }
        for(int a=0;a<n-3;a++){
            if(a>0 && nums[a]==nums[a-1]){
                continue;
            }
            if((long)nums[a]+nums[a+1]+nums[a+2]+nums[a+3]>target){
                break;//剪枝
            }
            if((long)nums[a]+nums[n-1]+nums[n-2]+nums[n-3]<target){
                continue;
            }
            for(int b=a+1;b<n-2;b++){
                if(b>a+1 && nums[b]==nums[b-1]){
                    continue;
                }
                if((long)nums[a]+nums[b]+nums[b+1]+nums[b+2]>target){
                    break;//这里报错因为上面for循环里开始写的是b<n,这里的b+2和b+1越界
                }//剪枝
                if((long)nums[a]+nums[b]+nums[n-1]+nums[n-2]<target){
                    continue;
                }
                int c=b+1;
                int d=n-1;
                while(c<d){
                    long sum=nums[a]+nums[b]+nums[c]+nums[d];
                    if(sum==target){
                        List<Integer> list=new ArrayList<Integer>();
                        list.add(nums[a]);
                        list.add(nums[b]);
                        list.add(nums[c]);
                        list.add(nums[d]);
                        ans.add(list);
                        while(c<d && nums[c]==nums[c+1]){
                            c++;
                        }
                        c++;
                        while(c<d && nums[d]==nums[d-1]){
                            d--;
                        }
                        d--;
                    } else if(sum<target){
                        c++;
                    }else{
                        d--;
                    }
                }
            }
        }
        return ans;
    }
}

思路:与前面的三数之和很相似,先对数组进行排序,然后创建一个二重数组来保存最终答案。

当数组中的值小于4个时,直接返回空数组。

然后设置abcd四个下标,a从第一个元素开始到倒数第四个,b从a的下一个开始到倒数第三个;c从b的下一个开始,d从最后一个开始。

其中还有一些剪枝函数,比如当nums[a]+nums[a+1]+nums[a+2]+nums[a+3]>target时,就可以直接跳出循环,因为后面的数都比这四个数大,无论如何也找不到=target的数。其余类似。

最后将符合条件的数添加到数组中,将符合条件的数组添加到二重数组中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值