LeetCode18. 四数之和

一、题目描述

☆☆☆☆二、解法

思路:与三数之和思想一样,排序+对撞指针。 时间复杂度 O(n^3)+O(nlogn) -> O(n^3)

需要注意去重以及剪枝,小细节非常多。

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> res = new ArrayList<>();
        if (nums == null || nums.length < 4) return res;
        Arrays.sort(nums);

        int len = nums.length;
        for (int i = 0; i < len - 3; i++) {
            if (i > 0 && nums[i] == nums[i - 1]) continue; // 去重
            if (nums[i] + nums[i+1] + nums[i+2] + nums[i+3] > target) return res; // 【剪枝】
            if (nums[i] + nums[len-3] + nums[len-2] + nums[len-1] < target) continue; // 【剪枝】
            for (int j = i + 1; j < len - 2; j++) {
                // 注意j的范围,不能是 j>0,否则过不了用例 [0,0,0,0] , 0
                if (j > i + 1 && nums[j] == nums[j - 1]) continue; // 去重
                if (nums[i] + nums[j] + nums[j+1] + nums[j+2] > target) break; // 【剪枝】
                if (nums[i] + nums[j] + nums[len-2] + nums[len-1] < target) continue; // 【剪枝】
                int start = j + 1, end = len - 1;
                while (start < end) {
                    int tempSum = nums[i] + nums[j] + nums[start] + nums[end];
                    if (tempSum > target) {
                        end --;
                    }else if (tempSum < target) {
                        start ++;
                    }else {
                        res.add(Arrays.asList(nums[i],nums[j],nums[start],nums[end]));
                        while (start < end && nums[start] == nums[start + 1]) start ++; // 去重
                        while (start < end && nums[end] == nums[end - 1]) end --; // 去重
                        start ++;
                        end --;
                    }
                }
            }
        }
        return res;
    }
}

 

posted @ 2020-12-11 11:21  不学无墅_NKer  阅读(68)  评论(0编辑  收藏  举报