LeetCode -- 4Sum
Question:
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)
Analysis: 这是2Sum的变种。
1. 暴力求解,4个for循环,依次求和,找到与target相等的元素,但是时间代价高,容易时间超时。
代码如下:
public class Solution { public List<List<Integer>> fourSum(int[] nums, int target) { int[] nums1 = sort(nums); List<List<Integer>> list = new ArrayList<List<Integer>>(); for(int i=0; i<nums1.length; i++) { for(int j=i+1; j<nums1.length; j++) { for(int k=j+1; k<nums1.length; k++) { for(int t=k+1; t<nums1.length; t++) { int sum = nums1[i] + nums1[j] + nums1[k] + nums1[t]; if(sum == target) { List<Integer> l = new ArrayList<Integer>(); l.add(nums1[i]); l.add(nums1[j]); l.add(nums1[k]); l.add(nums1[t]); list.add(l); } } } } } return list; } public int[] sort(int[] l) { for(int i=0; i<l.length; i++) { for(int j=i+1; j<l.length; j++) { if(l[i] > l[j]) { int t = l[i]; l[i] = l[j]; l[j] = t; } } } return l; } }
2. 方法二。首先对数组排序,用两层for循环,然后用两个指针分别指向剩余元素中最大的和最小的,四个数相加后若大于target则大指针前移,若小于target则小指针后移。注意避免重复放入结果集中。
代码如下:
public class Solution { public List<List<Integer>> fourSum(int[] nums, int target) { Arrays.sort(nums); List<List<Integer>> res = new ArrayList<List<Integer>>(); HashSet<List<Integer>> set = new HashSet<List<Integer>>(); for(int i=0; i<nums.length; i++) { for(int j=i+1; j<nums.length; j++) { int k = j + 1; int l = nums.length - 1; while(k < l) { int sum = nums[i] + nums[j] + nums[k] + nums[l]; if(sum < target) k++; else if(sum > target) l--; else { List<Integer> li = new ArrayList<Integer>(); li.add(nums[i]); li.add(nums[j]); li.add(nums[k]); li.add(nums[l]); if(!set.contains(li)) { res.add(li); set.add(li); } k++; l--; } } } } return res; } }