题目18:
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] ]
分析:
public class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
//用两个循环控制(内循环、外循环)
//one at the end of the outer loop (i-loop)
// the other at the end of the inner loop (j-loop)
//the function return immediately when nums[i]*4 > target
//the inner loop break immediately when nums[j]*4 < target.
List<List<Integer>> list=new ArrayList<List<Integer>>();
Arrays.sort(nums);
int len=nums.length;
for(int i=0;i<len-3;i++){
if(nums[i]*4>target) return list;
for(int j=len-1;j>i+2;j--){
if(nums[j]*4<target)break;
int remain=target-nums[i]-nums[j];
int low=i+1,high=j-1;
while(low<high){
int sum=nums[low]+nums[high];
if(sum>remain)high--;//如果比剩下的大,坐移
else if(sum<remain)low++;//如果比剩下的小,右移
else{
//相同
list.add(Arrays.asList(nums[i],nums[low],nums[high],nums[j]));//将该组数据存入list
//在内循环寻找相同的解
while(++low<=high&&nums[low]==nums[low-1])continue;
while(--high>=low&&nums[high]==nums[high+1])continue;
}
}
while(j>=1&&nums[j]==nums[j-1])--j;//跳出内循环
}
while(i<len-1&&nums[i]==nums[i+1])++i;//跳出外循环
}
return list;
}
}
题目454:
Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k,
l)
there are such that A[i] + B[j] + C[k] + D[l]
is zero.
To make problem a bit easier, all A, B, C, D have same length of N where 0 ≤ N ≤ 500. All integers are in the range of -228 to 228 - 1 and the result is guaranteed to be at most 231 - 1.
Example:
Input: A = [ 1, 2] B = [-2,-1] C = [-1, 2] D = [ 0, 2] Output: 2 Explanation: The two tuples are: 1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0 2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0分析:
class Solution {
public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {
//给定四个长度相同的数组,返回由他们四个组成之和为0的组合数。该题不同于4Sum的在于,每个元素的解限定了范围
//思路:使用HashMap实现,先将A和B的组合方法,之后再查找C和D的结果是否存在它们俩的绝对值和,可能存在多对
//只需要将和累加即可
//注意:暴力解法肯定TLM,该题不考虑统一数组中重复数据的影响
HashMap<Integer,Integer> hm=new HashMap<Integer,Integer>();
int count=0;
for(int i=0;i<A.length;i++){
for(int j=0;j<B.length;j++){
int sum=A[i]+B[j];
hm.put(sum,hm.getOrDefault(sum,0)+1);
}
}
//查找匹配
for(int i=0;i<C.length;i++){
for(int j=0;j<D.length;j++){
int sum=C[i]+D[j];
count+=hm.getOrDefault(-1*sum,0);
}
}
return count;
}
}