18. Suma de cuatro números
Dada una matriz nums que contiene n enteros y un objetivo de valor objetivo, determine si hay cuatro elementos a, b, c y d en nums, de modo que el valor de a + b + c + d sea igual al objetivo. Encuentre todos los cuádruples que satisfacen la condición y no se repiten.
Nota:
La respuesta no puede contener cuádruples repetidos.
Tomando prestada la función de la suma de tres números en la publicación anterior del blog, hice una poda
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
int start = 0;
int len = nums.length;
//先排序
Arrays.sort(nums,0,len);
List<List<Integer>> res = new ArrayList<List<Integer>>();
for(;start < len - 3; start++){
if(start > 0 && nums[start] == nums[start - 1])
continue;
int min = nums[start] + nums[start + 1] + nums[start + 2] + nums[start + 3];
int max = nums[start] + nums[len - 1] + nums[len - 2] + nums[len - 3];
if(min > target)
break;
if(max < target)
continue;
int tar = target - nums[start];
List<List<Integer>> tmp = threeSum(nums, start+1,tar);
if(!tmp.isEmpty()){
for(List<Integer> temp : tmp){
temp.add(nums[start]);
Collections.sort(temp);
res.add(temp);
}
}
}
res = new ArrayList<List<Integer>>(new HashSet<List<Integer>>(res));
return res;
}
public List<List<Integer>> threeSum(int[] nums,int p,int target) {
//时间复杂度O(n^2)
List<List<Integer>> res = new ArrayList<List<Integer>>();
int q,k;
if(nums.length - p < 3)
return res;
int initial = p;
for(;p < nums.length - 2; ++p){
q = nums.length - 1;
k = p + 1;
//最外层定一个从左向右遍历
//另两个变量相互夹逼找结果
if(p - 1 >= initial && nums[p] == nums[p - 1])
continue;
int min = nums[p] + nums[p + 1] + nums[p + 2];
int max = nums[p] + nums[q] + nums[q - 1];
if(min > target)
break;
if(max < target)
continue;
while(k < q){
if(nums[p] + nums[q] + nums[k] > target){
--q;
while(q > p + 1 && nums[q] == nums[q + 1])
--q;
}else{
if(nums[p] + nums[q] + nums[k] < target){
++k;
while(k < q && nums[k] == nums[k - 1])
++k;
}else{
List<Integer> tmp = new ArrayList<Integer>();
tmp.add(nums[p]);
tmp.add(nums[k]);
tmp.add(nums[q]);
res.add(tmp);
++k;
--q;
while(k < q && nums[k] == nums[k - 1]&& nums[q] == nums[q + 1])
++k;
}
}
}
}
return res;
}
}