4Sum——LeetCode

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:

  • Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
  • 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)

题目大意:跟3Sum类似,这个题是在一个数组中找出4个数的和等于target,如果还用3Sum这种做法,那么复杂度会到O(N^3),效率有点不能忍。

第一种:我想到的第一种方法是枚举a+b的和,放入一个数组,然后对这个数组排序,然后以Binary Search查找target-c-d是否存在于这个数组中,这里有个问题就是排序数组还要记录a、b的下标,只能定义class或者搞个二维数组,时间复杂服是O(N^2*logN)。

To add...

第二种:后来又想到一种方法就是把枚举的a+b的和放入HashMap,以a+b之和作为key,以这两个数的下标作为value,如果分散平均的话这样的时间复杂度是O(N^2),最坏情况是所有的数都一样,那么n^2个数的和只有一个key,List里有n^2个和,退化到O(N^4)。

    public List<List<Integer>> fourSum(int[] num, int target) {

        List<List<Integer>> res = new ArrayList<>();

        if (num == null || num.length < 4) {

            return res;

        }

        int len = num.length;

        Map<Integer, List<Integer>> map = new HashMap<>();

        Set<String> unique = new HashSet<>();

        for (int i = 0; i < len; i++) {

            for (int j = i + 1; j < len; j++) {

                int key = num[i] + num[j];

                if (map.get(key) == null) {

                    List<Integer> list = new ArrayList<>();

                    list.add(i * len + j);

                    map.put(key, list);

                } else {

                    List<Integer> list = map.get(key);

                    list.add(i * len + j);

                    map.put(key, list);

                }

            }

        }

        for (int i = 0; i < len; i++) {

            for (int j = i + 1; j < len; j++) {

                int key = target - num[i] - num[j];

                List<Integer> list = map.get(key);

                if (list == null || list.isEmpty()) {

                    continue;

                }

                for (Integer pos : list) {

                    int x = pos / len;

                    int y = pos % len;

                    if (i == x || i == y || j == x || j == y || x == y)

                        continue;

                    int[] t = new int[]{num[i], num[j], num[x], num[y]};

                    Arrays.sort(t);

                    String uni = String.valueOf(t[0]) + t[1] + t[2] + t[3];

                    if (!unique.contains(uni)) {

                        unique.add(uni);

                        res.add(Arrays.asList(t[0], t[1], t[2], t[3]));

                    }

                }

            }

        }

        return res;

    }

 

你可能感兴趣的:(LeetCode)