【LeetCode】 018. 4Sum

来源:互联网 发布:双十一大学生网购数据 编辑:程序博客网 时间:2024/04/29 20:34

Given an array S of n integers, are there elements abc, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

Note: The solution set must not contain duplicate quadruplets.

For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0.A solution set is:[  [-1,  0, 0, 1],  [-2, -1, 1, 2],  [-2,  0, 0, 2]]

public class Solution {    public List<List<Integer>> fourSum(int[] nums, int target) {        List<List<Integer>> res = new LinkedList<List<Integer>>();        Arrays.sort(nums);        if (nums.length < 4) {            return res;        }        int max = nums[nums.length - 1];        if (nums[0] * 4 > target || 4 * max < target) {            return res;        }        for (int i = 0; i < nums.length - 3; i++) {            int first = nums[i];            if (i > 0 && first == nums[i - 1]) {                continue;            }            if (first + 3 * max < target) {                continue;            }            if (4 * first > target) {                break;            }            if (4 * first == target) {                if (nums[i + 3] == first) {                    res.add(Arrays.asList(first, first, first, first));                }                break;            }            threeSum(nums, target - first, i + 1, res, first);        }        return res;    }        private void threeSum(int[] nums, int target, int start, List<List<Integer>> res, int first) {        if (start > nums.length - 3) {            return;        }        int max = nums[nums.length - 1];        if (3 * nums[start] > target || 3 * max < target) {            return;        }        for (int i = start; i < nums.length - 2; i++) {            int second = nums[i];            if (i > start && second == nums[i - 1]) {                continue;            }            if (second + 2 * max < target) {                continue;            }            if (3 * second > target) {                break;            }            if (3 * second == target) {                if (nums[i + 2] == second) {                    res.add(Arrays.asList(first, second, second, second));                }                break;            }            twoSum(nums, target - second, i + 1, res, first, second);        }    }        private void twoSum(int[] nums, int target, int start, List<List<Integer>> res, int first, int second) {        if (start > nums.length - 2) {            return;        }        int end = nums.length - 1;        int max = nums[end];        if (2 * nums[start] > target || 2 * max < target) {            return;        }        while (start < end) {            int sum = nums[start] + nums[end];            if (sum == target) {                res.add(Arrays.asList(first, second, nums[start], nums[end]));                while (start < end && nums[start] == nums[start + 1]) {                    start++;                }                while (start < end && nums[end] == nums[end - 1]) {                    end--;                }                start++;                end--;            } else if (sum < target) {                start++;            } else {                end--;            }        }        return;    }}


0 0