问题
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]
]
分析:
4Sum问题。从discuss中找到了一个非常巧妙的方法,而且效率很高,就是从4+简化成3+再简化成2+,换一种评论中的说法就是玩五阶魔方的思路就是从五阶降到四阶,然后再从四阶降到三阶,最后再按照玩三阶魔方的老套路解决问题。嗯,这个思路有点类似!
。其中很重要的就是各种限制条件,还有去重。
java
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> ans = new ArrayList<>();
if(nums==null || nums.length<4 )
return ans;
Arrays.sort(nums);
if(nums[nums.length-1]*4 < target)
return ans;
for(int i = 0; i < nums.length - 3; i++){
if(i>0 && nums[i]==nums[i-1])
continue;
if(nums[i] + nums[nums.length-1]*3 < target)
continue;
if(nums[i]*4 > target)
break;
threeSumForFourSum(nums, ans, i+1, target - nums[i]);
}
return ans;
}
public void threeSumForFourSum(int[] nums, List<List<Integer>> ans, int low, int target){
for(int i = low; i < nums.length - 2; i++){
if(i > low && nums[i] == nums[i-1])
continue;
if(nums[i] + nums[nums.length-1]*3 < target)
continue;
if(nums[i]*3 > target)
return;
twoSumForThreeSum(nums, ans, i+1, target - nums[i], low-1);
}
return;
}
public void twoSumForThreeSum(int[] nums, List<List<Integer>> ans, int low, int target, int firstinx){
int i = low, j = nums.length - 1;
while(i < j){
if(nums[i] + nums[j] == target){
ans.add(Arrays.asList(nums[firstinx], nums[low-1], nums[i], nums[j]));
while(i<j && nums[i] == nums[i+1]) i++;
i++;
while(i<j && nums[j] == nums[j-1]) j--;
j--;
}
else if(nums[i] + nums[j] < target)
i++;
else
j--;
}
return;
}
}