Leetcode18 4Sum

Posted chason95

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode18 4Sum相关的知识,希望对你有一定的参考价值。

暴力解法O(n^4),太恐怖了。

3Sum思路:转化,降维,排序+两层外循环内部两指针(一左一右),O(n^3)。

 

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> ans = new ArrayList<>();
        if(nums==null||nums.length<4) return ans;
        Arrays.sort(nums);
        for(int i=0;i<nums.length-3;i++) {
            if(i==0||(i>0&&nums[i]!=nums[i-1])) {
                for(int j=i+1;j<nums.length-2;j++) {
                    if(j>0&&nums[j]!=nums[j-1]) {
                        int low=j+1,high=nums.length-1,temp_target=target-nums[i]-nums[j];
                        while(low<high) {
                            if(nums[low]+nums[high]==temp_target) {
                                ans.add(Arrays.asList(nums[i],nums[j],nums[low],nums[high]));
                                while(low<high&&nums[low]==nums[low+1]) low++;
                                while(low<high&&nums[high]==nums[high-1]) high--;
                                low++;high--;
                            }
                            else if(nums[low]+nums[high]>temp_target) {
                                high--;
                            }
                            else {
                                low++;
                            }
                        }
                    }
                }
            }
        }
        return ans;
    }
}
出错:
Input:[0,0,0,0] 0
Output:[]
Expected:[[0,0,0,0]]
查错的过程对
if(i==0||(i>0&&nums[i]!=nums[i-1]))
理解的更深了。i==0并不只是保证nums[i-1]存在,而是对于第一个一定要进入循环。
更正后可用:
class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> ans = new ArrayList<>();
        if(nums==null||nums.length<4) return ans;
        Arrays.sort(nums);
        for(int i=0;i<nums.length-3;i++) {
            if(i==0||(i>0&&nums[i]!=nums[i-1])) {
                for(int j=i+1;j<nums.length-2;j++) {
                    if(j==i+1||(j>i+1&&nums[j]!=nums[j-1])) {
                        int low=j+1,high=nums.length-1,temp_target=target-nums[i]-nums[j];
                        while(low<high) {
                            if(nums[low]+nums[high]==temp_target) {
                                ans.add(Arrays.asList(nums[i],nums[j],nums[low],nums[high]));
                                while(low<high&&nums[low]==nums[low+1]) low++;
                                while(low<high&&nums[high]==nums[high-1]) high--;
                                low++;high--;
                            }
                            else if(nums[low]+nums[high]>temp_target) {
                                high--;
                            }
                            else {
                                low++;
                            }
                        }
                    }
                }
            }
        }
        return ans;
    }
}

两次70ms附近 20%多,最好34ms,79%。还是有更好的方法的。

更好的方法:15ms方法 O(n^3)加剪枝,下次做可以尝试加上。11ms方法dfs,略复杂,下次想看可以看不想看算了。

 
 
 
 
 
 
 
 

以上是关于Leetcode18 4Sum的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode——18. 4Sum

[leetcode-18-4Sum]

LeetCode 18. 4Sum

LeetCode:18. 4Sum(Medium)

[LeetCode] 18. 4Sum

Leetcode18 4Sum