Given an array S of n integers, are there elements a,b,c, andd 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)
public class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
Arrays.sort(nums);
kSum(result, new ArrayList<Integer>(), nums, target, 4, 0, nums.length-1);
return result;
}
private void kSum(List<List<Integer>> result,List<Integer> cur, int[] nums, int target,
int k, int start, int end) {
if(k == 0 || nums.length ==0 || start>end)
return;
if(k == 1){
for (int i = start; i <= end; i++) {
if (nums[i] == target) {
cur.add(nums[i]);//添加
result.add(new ArrayList<Integer>(cur));//放入到结果中
cur.remove(cur.size()-1);//移除
}
}
return;
}
if(k == 2){
int sum;
while (start < end){
sum = nums[start] + nums[end];
if(sum == target){
cur.add(nums[start]);
cur.add(nums[end]);
result.add(new ArrayList<Integer>(cur));
cur.remove(cur.size()-1);
cur.remove(cur.size()-1);
//避免重复
while(start < end && nums[start] == nums[start+1])
++start;
++start;
while(start < end && nums[end] == nums[end-1])
--end;
--end;
}else if(sum < target){
//避免重复
while(start < end && nums[start] == nums[start+1])
++start;
++start;
}else{
while(start < end && nums[end] == nums[end-1])
--end;
--end;
}
}
return;
}
//每次务必会进行数据预处理,简单的情况判断,避免了不必要的情况
if(k*nums[start] > target || k*nums[end] < target)
return;
for(int i = start; i <= (end-k+1); i++){
if(i > start && nums[i] == nums[i-1])
continue;//避免了重复
if(k*nums[i] <= target) {
cur.add(nums[i]);
kSum(result, cur, nums, target - nums[i], k - 1, i + 1, end);
//开始了神奇的递归了
cur.remove(cur.size() - 1);//输入的地方总要对应一个输出
}
}
}
}
//k=0,1太简单了,k=2,见上一题
这题跟之前的几道题是差不多的~