leetcode刷题(数组list)10—四数之和

18. 四数之和

给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。
注意:
答案中不可以包含重复的四元组。

借用上个博文里三数之和的函数,做了些剪枝

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        int start = 0;
        int len = nums.length;
         //先排序
        Arrays.sort(nums,0,len);
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        for(;start < len - 3; start++){
            if(start > 0 && nums[start] == nums[start - 1])
             continue;
            int min = nums[start] + nums[start + 1] + nums[start + 2] + nums[start + 3];
            int max = nums[start] + nums[len - 1] + nums[len - 2] + nums[len - 3];
            if(min > target)
                break;
            if(max < target)
                continue;
            int tar = target - nums[start];
            List<List<Integer>> tmp = threeSum(nums, start+1,tar);
            if(!tmp.isEmpty()){
                for(List<Integer> temp : tmp){
                    temp.add(nums[start]);
                    Collections.sort(temp);
                    res.add(temp);
                }
            }
          
        }
        res  = new ArrayList<List<Integer>>(new HashSet<List<Integer>>(res));
        return res;
    }
    public List<List<Integer>> threeSum(int[] nums,int p,int target) {
        //时间复杂度O(n^2)
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        int q,k;
        if(nums.length - p < 3)
            return res;
        int initial = p;
       for(;p < nums.length - 2; ++p){
           q = nums.length - 1; 
           k = p + 1;
           //最外层定一个从左向右遍历
           //另两个变量相互夹逼找结果
           if(p - 1 >= initial && nums[p] == nums[p - 1])
                continue; 
           int min = nums[p] + nums[p + 1] + nums[p + 2];
            int max = nums[p] + nums[q] + nums[q - 1];
            if(min > target)
                break;
            if(max < target)
                continue;
          
           while(k < q){
                if(nums[p] + nums[q] + nums[k] > target){
               --q;
               while(q > p + 1 && nums[q] == nums[q + 1])
                 --q;
           }else{
               if(nums[p] + nums[q] + nums[k] < target){
                    ++k;
                    while(k < q && nums[k] == nums[k - 1])
                        ++k;
               }else{
                   List<Integer> tmp = new ArrayList<Integer>(); 
                   tmp.add(nums[p]);
                   tmp.add(nums[k]);
                   tmp.add(nums[q]);
                   res.add(tmp);
                   ++k;
                   --q;
                   while(k < q && nums[k] == nums[k - 1]&& nums[q] == nums[q + 1])
                        ++k;
               }
           }
           }
       }
         
         return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值