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;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_38754625/article/details/108411614
今日推荐