编号454:四数相加II
给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。
「例如:」
输入: A = [ 1, 2] B = [-2,-1] C = [-1, 2] D = [ 0, 2]
输出: 2
「解释:」
两个元组如下:
- (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
- (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0
思路
本题咋眼一看好像和第18题. 四数之和,第15题.三数之和差不多,其实差很多。
「本题是使用哈希法的经典题目,而第18题. 四数之和,第15题.三数之和 并不合适使用哈希法」,因为三数之和和四数之和这两道题目使用哈希法在不超时的情况下做到对结果去重是很困难的,很有多细节需要处理。
「而这道题目是四个独立的数组,只要找到A[i] + B[j] + C[k] + D[l] = 0就可以,不用考虑有重复的四个元素相加等于0的情况,所以相对于题目18. 四数之和,题目15.三数之和,还是简单了不少!」
如果本题想难度升级:就是给出一个数组(而不是四个数组),在这里找出四个元素相加等于0,答案中不可以包含重复的四元组,大家可以思考一下,后续的文章我也会讲到的。
本题解题步骤:
- 首先定义 一个unordered_map,key放a和b两数之和,value 放a和b两数之和出现的次数。
- 遍历大A和大B数组,统计两个数组元素之和,和出现的次数,放到map中。
- 定义int变量count,用来统计a+b+c+d = 0 出现的次数。
- 在遍历大C和大D数组,找到如果 0-(c+d) 在map中出现过的话,就用count把map中key对应的value也就是出现次数统计出来。
- 最后返回统计值 count 就可以了
代码
public class 四五四题四数相加 {
public static void main(String[] args) {
int [] A = {1,2};
int [] B = {-2,-1};
int [] C = {-1, 2};
int [] D = { 0, 2};
int i = fourSum(A, B, C, D);
System.out.println(i);
}
//利用HsahMap求解四数相加
public static int fourSum(int[] A, int[] B, int[] C, int[] D) {
HashMap<Integer, Integer> map = new HashMap<>();
int count = 0;
for (int i = 0; i < A.length; i++) {
for (int j = 0; j < B.length; j++) {
int key = A[i] + B[i];
//map.put( A[i]+B[i], map.getOrDefault(A[i]+B[i],0)+1);
if (map.containsKey(key)) {
map.put(key, map.get(key) + 1);
}
map.put(key, 1);
}
}
for (int i = 0; i < C.length; i++) {
for (int j = 0; j < D.length;j++) {
int key = C[i] + D[j];
count += map.getOrDefault(-key, 0);
}
}
return count;
}
}