题目:
https://leetcode-cn.com/problems/4sum-ii/
题解:哈希表
本题最直观最暴力的方法应该是直接遍历四个数组,但是时间复杂度O(n^4) 太高,所以得换个思路思考。A+B+C+D = 0 可以变换为 A+B = -(C+D),可以按照这个想法将4层嵌套循环减少为2层循环,再将结果存放在哈希表中,从哈希表中找出满足条件的记录即可。
1.遍历A,B求和存放在哈希表中。
2.遍历C,D求和存放在哈希表中。
3.在哈希表中找出满足 A+B = -(C+D) 的记录。
每次只需要遍历两个数组,所以时间复杂度为:O(n^2)。
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
Map<Integer, Integer> sumMap1 = buildSumMap(nums1, nums2);
Map<Integer, Integer> sumMap2 = buildSumMap(nums3, nums4);
int count = 0;
for (Map.Entry<Integer, Integer> entry : sumMap1.entrySet()) {
// A,B的和
Integer num = entry.getKey();
// A+B出现的次数
Integer numCount = entry.getValue();
// -(C+D) 出现的次数
Integer targetCount = sumMap2.get(-num);
if (targetCount != null) {
count += numCount * targetCount;
}
}
return count;
}
/**
* 两数和出现次数的哈希表
*
* @param nums1 数组1
* @param nums2 数组2
* @return key: 两数和, value:两数和出现的次数
*/
public Map<Integer, Integer> buildSumMap(int[] nums1, int[] nums2) {
Map<Integer, Integer> map = new HashMap<>(nums1.length);
for (int i = 0; i < nums1.length; i++) {
for (int j = 0; j < nums2.length; j++) {
int sum = nums1[i] + nums2[j];
int count = map.getOrDefault(sum, 0) + 1;
map.put(sum, count);
}
}
return map;
}