`
huntfor
  • 浏览: 201547 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

[leetcode]4Sum

 
阅读更多

新博文地址:[leetcode]4Sum

4Sum

Given an array S of n integers, are there elements a, b, c, 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 和3Sum Closest ,只需要在3Sum的外层再加一层循环即可。不了解的请戳这里。时间复杂度为O(n^3),但是我在网上看到一个算法时间复杂度只有O(n^2),但是空间复杂度太大,而且网上只提供了算法思想,并没有给出实现,本以为O(n^3)过不去,因此把O(n^2)的算法实现了一下。代码太长太丑,阅览请慎重:

 

List<List<Integer>> result = new ArrayList<List<Integer>>();
	Set<String> duplicate = new HashSet<String>();
	public List<List<Integer>> fourSum(int[] num, int target) {
		if (num == null || num.length < 4) {
			return result;
		}
		HashMap<Integer, Integer> hash = new HashMap<Integer, Integer>();
		Map<Integer, List<int[]>> twoSum = new HashMap<Integer, List<int[]>>();
		Set<Integer> processed = new HashSet<Integer>();
		for (int i = 0; i < num.length; i++) {
			hash.put(num[i], hash.containsKey(num[i]) ? hash.get(num[i]) + 1
					: 1);
			for (int j = i + 1; j < num.length; j++) {
				int[] node = new int[] { num[i], num[j] };
				if (twoSum.containsKey(num[i] + num[j])) {
					twoSum.get(num[i] + num[j]).add(node);
				} else {
					List<int[]> list = new ArrayList<int[]>();
					list.add(node);
					twoSum.put(num[i] + num[j], list);
				}
			}
		}
		for (int k : twoSum.keySet()) {
			if (processed.contains(k))
				continue;
			if (twoSum.containsKey(target - k)) {
				processed.add(k);
				if (target == k << 1) {
					for (int[] node1 : twoSum.get(k)) {
						for (int[] node2 : twoSum.get(k)) {
							if (node2 != node1) {
								process(node1, node2, hash);
							}
						}
					}
				} else {
					processed.add(target - k);
					List<int[]> list1 = twoSum.get(k);
					List<int[]> list2 = twoSum.get(target - k);
					for (int[] node1 : list1) {
						for (int[] node2 : list2) {
							process(node1, node2, hash);
						}
					}
				}

			}
		}
		return result;
	}
	private void process(int[] a, int[] b, HashMap<Integer, Integer> map) {
		int[] sum = new int[] { a[0], a[1], b[0], b[1] };
		Arrays.sort(sum);
		StringBuilder sb = new StringBuilder();
		Map<Integer, Integer> cloneMap = (HashMap<Integer, Integer>) map
				.clone();
		for (int i = 0; i < 4; i++) {
			sb.append(sum[i]);
			cloneMap.put(sum[i], cloneMap.get(sum[i]) - 1);
			if (cloneMap.get(sum[i]) < 0)
				return;
		}
		if (!duplicate.contains(sb.toString())) {
			duplicate.add(sb.toString());
			List<Integer> list = new ArrayList<Integer>();
			for(int i = 0; i < 4; list.add(sum[i++]));
			result.add(list);
		}
	}

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics