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;
    }

 

posted @ 2015-04-08 00:24  丶Blank  阅读(147)  评论(0编辑  收藏  举报