18 4sum

my solution:

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        Arrays.sort(nums);
        // for(int i = 0; i < nums.length;i++)
        // {
        //     System.out.print(nums[i]+" ");
        // }
        // System.out.println();
        HashSet<List<Integer>> set = new HashSet<List<Integer>>();
        
        for(int i = 0; i < nums.length-3; i++)
        {
            while(i>=1 && nums[i]==nums[i-1] && i < nums.length-3)
            {
                i++;
            }
            
            for(int j = i+1;j < nums.length-2; j++)
            { 
                for(int m = j+1; m < nums.length-1; m++)
                {
                    int sum3 = target -nums[i] - nums[j] - nums[m];
                    if(sum3 < nums[m+1] || sum3 > nums[nums.length-1])continue;
                    else{
                        int p = m+1,q = nums.length-1;
                        while(p <= q)
                        {
                            if(nums[p + (q-p)/2] == sum3) 
                            {
                              set.add(Arrays.asList(nums[i],nums[j],nums[m],sum3));   break;
                            }
                            else if(nums[p + (q-p)/2] > sum3) q = p + (q-p)/2 -1;
                            else p = p + (q-p)/2 + 1;
                        }
                    }
                }
            }
        }
   
        List<List<Integer>> ans = new LinkedList<>();
        for(List<Integer> list:set)
        {
            ans.add(list);
        }
        return ans;
    }
}

Better Solution:

To avoid duplicate list items, I skip unnecessary indices at two locations:

  • one at the end of the outer loop (i-loop)
  • the other at the end of the
    inner loop (j-loop).

To avoid useless computations, the following is kind of critical:

  • the function return immediately when nums[i]*4 > target
  • the inner loop break immediately when nums[j]*4 < target.

These two lines save quite some time due to the set up of the test cases in OJ.

public class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> list = new ArrayList<List<Integer>>();
        Arrays.sort(nums);
        int second = 0, third = 0, nexti = 0, nextj = 0;
        for(int i=0, L=nums.length; i<L-3; i++) {
            if(nums[i]<<2 > target) return list; // return immediately
            for(int j=L-1; j>i+2; j--) {
                if(nums[j]<<2 < target) break; // break immediately
                int rem = target-nums[i]-nums[j];
                int lo = i+1, hi=j-1;
                while(lo<hi) {
                    int sum = nums[lo] + nums[hi];
                    if(sum>rem) --hi;
                    else if(sum<rem) ++lo;
                    else {
                        list.add(Arrays.asList(nums[i],nums[lo],nums[hi],nums[j]));
                        while(++lo<=hi && nums[lo-1]==nums[lo]) continue; // avoid duplicate results
                        while(--hi>=lo && nums[hi]==nums[hi+1]) continue; // avoid duplicate results
                    }
                }
                while(j>=1 && nums[j]==nums[j-1]) --j; // skip inner loop
            }
            while(i<L-1 && nums[i]==nums[i+1]) ++i; // skip outer loop
        }
        return list;
    }

猜你喜欢

转载自blog.csdn.net/weixin_42521881/article/details/86257279