[LeetCode] 18. 4Sum ☆☆
Posted Strugglion
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LeetCode] 18. 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: 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] ]
解法1:
在 3Sum 的基础上再加一层循环即可,3Sum 时间复杂度为 O(n2),所以这个方法时间复杂度为 O(n3)。
public 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); for (int i = 0; i < nums.length - 3; i++) { if (i > 0 && nums[i] == nums[i - 1]) { continue; } int sum3 = target - nums[i]; // 后3个数之和需等于sum3 for (int j = i + 1; j < nums.length - 2; j++) { if (j > i + 1 && nums[j] == nums[j - 1]) { continue; } int sum2 = sum3 - nums[j]; // 后2个数之和需等于sum3 int left = j + 1, right = nums.length - 1; while (left < right) { if (nums[left] + nums[right] == sum2) { List<Integer> quad = new ArrayList<>(); quad.add(nums[i]); quad.add(nums[j]); quad.add(nums[left]); quad.add(nums[right]); res.add(quad); while (left < right && nums[left++] == nums[left]) {} while (left < right && nums[right--] == nums[right]) {} } else if (nums[left] + nums[right] < sum2) { while (left < right && nums[left++] == nums[left]) {} } else { while (left < right && nums[right--] == nums[right]) {} } } } } return res; } }
解法2:
先排序 (O(nlogn)),然后遍历整个数组,以每两个数的和作为key将两个数的index存于HashMap中,由于存在和相同的情况,因此HashMap中的每个键对应的是一个List,每个List中保存着多组index对,这一操作时间复杂度为 (O(n2))。
遍历每个key,计算出需要满足4Sum为target的另外一个2Sum,两个2Sum对应的List分别为listA和listB,遍历其中的每一组index,分别为[a0, a1] 和 [b0, b1]。为避免找到index重复的结果,只寻找满足 a0 < b0, a0 < b1, a1 < b0, a1 < b1 的结果,而因为本身就有 a0 < a1, b0 < b1,所以只需满足 a1 < b0 即可。判断找到的结果是否已存在,不存在再把结果加到res中。这一操作比较复杂,时间复杂度不好算,据说是(O(n2logn)),但LeetCode给出的结果是超时。。。。
public 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); HashMap<Integer, List<Integer[]>> map = new HashMap<>(); for (int i = 0; i < nums.length - 1; i++) { for (int j = i + 1; j < nums.length; j++) { int sum = nums[i] + nums[j]; Integer[] pair = {i, j}; if (!map.containsKey(sum)) { map.put(sum, new ArrayList<Integer[]>()); } map.get(sum).add(pair); } } Set<Integer> keys = map.keySet(); for (int key : keys) { List<Integer[]> listA = map.get(key); List<Integer[]> listB = map.get(target - key); if (listA != null && listB != null) { for (Integer[] pairA : listA) { int a0 = pairA[0], a1 = pairA[1]; for (Integer[] pairB : listB) { int b0 = pairB[0], b1 = pairB[1]; if (a1 < b0) { // 因为肯定存在: a0 < a1, b0 < b1 List<Integer> list = new ArrayList<>(); list.add(nums[a0]); list.add(nums[a1]); list.add(nums[b0]); list.add(nums[b1]); if (!res.contains(list)) res.add(list); } } } } } return res; } }
以上是关于[LeetCode] 18. 4Sum ☆☆的主要内容,如果未能解决你的问题,请参考以下文章