454.四数相加II
题目
要求
给你四个整数数组 nums1
、nums2
、nums3
和 nums4
,数组长度都是 n
,请你计算有多少个元组 (i, j, k, l)
能满足:
0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
思考过程
上来直接暴力破解,四层 for 循环,结果超时,代码如下:
/**
* 四数相加,最直观的,暴力破解,但是很大的可能会超时
* @param nums1
* @param nums2
* @param nums3
* @param nums4
* @return
*/
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
int count = 0;
for (int i : nums1) {
for (int j : nums2) {
for (int k : nums3) {
for (int m : nums4) {
if (i + j + k + m == 0) {
count ++;
}
}
}
}
}
return count;
}
换一个使用 map,然后成为三层 for 循环:
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
Map<Integer, Integer> map = new HashMap<>();
for (int num : nums4) {
map.put(num, map.getOrDefault(num, 0) + 1);
}
int count = 0;
for (int i : nums1) {
for (int j : nums2) {
for (int k : nums3) {
if (map.containsKey(-i - j - k)) {
count += map.getOrDefault(-i - j - k, 0);
}
}
}
}
return count;
}
继续能不能成为双层 for 循环呢?因为相加只能是两个数字,才可以判断,那我就把四个数组两两分组,然后相加试试看:
/**
* 分组 + 哈希表的思路,分成两组计算
* @param nums1
* @param nums2
* @param nums3
* @param nums4
* @return
*/
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
Map<Integer, Integer> map1 = new HashMap<>();
for (int i : nums1) {
for (int j : nums2) {
map1.put(i + j, map1.getOrDefault(i + j, 0) + 1);
}
}
int count = 0;
Map<Integer, Integer> map2 = new HashMap<>();
for (int i : nums3) {
for (int j : nums4) {
if (map1.containsKey(- i - j)) {
count += map1.get(- i - j);
}
}
}
return count;
}
基本上就是这样。