3数之和
给定n个整数的数组S,S中是否有元素a,b,c 使得a + b + c = 0?在数组中找到所有唯一的三元组 零的总和。
public static List<List<Integer>> threeSum(int[] nums){
List<List<Integer>> res=new ArrayList<>();
if(nums.length<3)return res;
Arrays.sort(nums);
final int target=0;
for (int i = 0; i <nums.length-2 ; ++i) {
if(i>0 && nums[i]==nums[i-1]) continue;
int j=i+1;
int k=nums.length-1;
while (j<k){
if(nums[i]+nums[j]+nums[k]<target){
++j;
while (nums[j]==nums[j-1] && j<k) ++j;
}else if(nums[i]+nums[j]+nums[k]>target){
--k;
while (nums[k]==nums[k+1]&&j<k)--k;
}else{
res.add(Arrays.asList(nums[i],nums[j],nums[k]));
++j;
--k;
while (nums[j]==nums[j-1]&&j<k)++j;
while (nums[k]==nums[k+1]&&j<k)--k;
}
}
}
return res;
}
最接近的3数之和
给定n个整数的数组S,在S中找到三个整数,使得 总和最接近给定数字target。返回三者的总和 整数。您可以假设每个输入都只有一个解决方案。 例如,给定数组S = {-1 2 1-4},目标 = 1。 最接近目标的总和为2。(-1 + 2 + 1 = 2)。
public static int threeSumCloses(int[] nums,int target){
int res=0;
int min=Integer.MAX_VALUE;
Arrays.sort(nums);
for (int i = 0; i <nums.length-1 ; ++i) {
int j=i+1;
int k=nums.length-1;
while (j<k){
final int sum=nums[i]+nums[j]+nums[k];
final int gap=Math.abs(sum-target);
if(gap<min){
res=sum;
min=gap;
}
if(sum<target)++j;
else --k;
}
}
return res;
}
4数之和
给定n个整数的数组S,是否有元素a,b,c和d 在S中,a + b + c + d = 目标?在中查找所有独特的四位数 给出目标总和的数组。 注: 四元组 (a,b,c,d) 中的元素必须按非降序排列。 例如,给定数组S = {1 0 -2 2},目标 = 0。
map缓存
public static List<List<Integer>> fourSum(int[] nums,int target){
List<List<Integer>> res=new ArrayList<>();
if(nums.length<4)return res;
Arrays.sort(nums);
for (int i = 0; i <nums.length-3 ; ++i) {
if(i>0&&nums[i]==nums[i-1])continue;
for (int j = i+1; j <nums.length-2 ; ++j) {
if(j>i+1&&nums[j]==nums[j-1])continue;
int k=j+1;
int l=nums.length-1;
while (k<l){
final int sum=nums[i]+nums[j]+nums[k]+nums[l];
if(sum<target){
++k;
while (nums[k]==nums[k-1]&&k<l)++k;
}else if(sum>target){
--l;
while (nums[l]==nums[l+1]&&k<l)--l;
}else{
res.add(Arrays.asList(nums[i],nums[j],nums[k],nums[l]));
++k;
--l;
while (nums[k]==nums[k-1]&&k<l)++k;
while (nums[l]==nums[l+1]&&k<l)--l;
}
}
}
}
return res;
}
public static List<List<Integer>> fourSumTwo(int[] nums,int target){
List<List<Integer>> res=new ArrayList<>();
if(nums.length<4)return res;
Arrays.sort(nums);
final HashMap<Integer,ArrayList<int[]>> cache=new HashMap<>();
for (int i = 0; i <nums.length ; ++i) {
for (int j = i+1; j <nums.length ; ++j) {
ArrayList<int[]> value=cache.get(nums[i]+nums[j]);
if(value==null){
value=new ArrayList<>();
cache.put(nums[i]+nums[j],value);
}
value.add(new int[]{i,j});
}
}
final HashSet<String> used=new HashSet<>();
for (int i = 0; i <nums.length ; ++i) {
if(i>0&&nums[i]==nums[i-1])continue;
for (int j = i+1; j <nums.length-2 ; ++j) {
if(j>i+1&&nums[j]==nums[j-1])continue;
final ArrayList<int[]> list=cache.get(target-nums[i]-nums[j]);
if(list==null)continue;
for (int[] pair:list){
if(j>=pair[0])continue;
final Integer[] sol=new Integer[]{nums[i],nums[j],nums[pair[0]],nums[pair[1]]};
Arrays.sort(sol);
final String key=Arrays.toString(sol);
if(!used.contains(key)){
res.add(Arrays.asList(sol));
used.add(key);
}
}
}
}
return res;
}