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)
比如:{-4,-1,-1,0,1,2} -1,当s指向第一个-1且v指向第二个-1的时候,如果按照旧的判断方式,v会触发重复性判断,显然这是错误的,因为s位处在这个位置的时候,v并没有重复计算,只有当v和s没有相邻的时候,v的重复性判断才不会漏解。因此,对v的重复性条件要加以限制。
代码如下:
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> lists=new ArrayList<List<Integer>>();
if(nums.length<=2)return lists;
Arrays.sort(nums);
int len =nums.length;
for (int i = 0; i < len-3; i++) {//len-2已经包含所有情况
if(i>0&&nums[i]==nums[i-1])continue;//这里是i-1与i的判断因为for循环i++了
for(int j=i+1;j<len-2;j++){
if(j>i+1&&nums[j]==nums[j-1])continue;//j>i+1重复性判断的限制
int start = j+1;
int end = len-1;
int s = nums[i];
int v = nums[j];
while(start<end){
Integer[] arr = new Integer[4];
int re = s+v+nums[start]+nums[end];
if(re>target){
end--;
}else if(re<target){
start++;
}else{
arr[0]=s;
arr[1]=v;
arr[2]=nums[start];
arr[3]=nums[end];
ArrayList<Integer> tr = new ArrayList<Integer>();
tr.add(arr[0]);
tr.add(arr[1]);
tr.add(arr[2]);
tr.add(arr[3]);
lists.add(tr);
while (start < end && nums[start] == nums[start+1]) start++;
while (start < end && nums[end] == nums[end-1]) end--;
start++;//对于同一个s 可能有多个适配的情况;
end--;
}
}
}
}
return lists;
}