第454题.四数相加II
题目:
分析:
这道题第一眼看上去没有思路,看完代码随想录的思路后,有所感悟:
首先,我们只要求四个数组中各出一个元素之和为0,直接for循环遍历,显然时间复杂度过于离谱了。那我们应该这么办呢?我们可以先计算两个数组各个元素之和,这样的时间复杂度为O(n2),然后,将我们计算出来的两个元素之和作为key,次数作为value 添加到map中。
然后,再计算另外两个数组直接元素的和,在我们的 map 中,寻找是否有为其相反数的 key,将key 对应的次数累加到 res上,若没有,就累加0。
那这么样才能将 次数更新到对应的数组和中呢,这需要一个方法getOrDefault(key, default)——在下面会给出展示。
这道题为什么使用哈希表呢?
- 不要求去重,只要求次数。——我们只需要寻找对应的元素的出现次数即可,所以使用 HashMap。
这道题为什么可以拆解为两两数组之和?
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
可以化简为如下的形式。nums1[i] + nums2[j] == -nums3[k] - nums4[l]
getOrDefault方法:
public V getOrDefault(Object key,
V defaultValue)说明从界面: Map复制
返回到指定键所映射的值,或 defaultValue如果此映射包含该键的映射。
Specified by:
getOrDefault在界面 Map<K,V>
参数
key - 要返回其关联值的键
defaultValue - 键的默认映射
结果
指定键映射到的值,如果此映射不包含该键的映射
若key存在,返回其对应的value,若key不存在,返回我们设定的默认值 default。
代码:
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
int res = 0;
Map<Integer, Integer> map = new HashMap<>();
for(int i : nums1){
for(int j : nums2){
int sum = i + j;
// 将该sum加入,若sum没有出现过,默认为0,否则将值变为原来的值+1
map.put(sum, map.getOrDefault(sum, 0) + 1);
}
}
for(int i : nums3){
for(int j : nums4){
// 寻找map中是否有 相反数,若有,那么说明我们找到了能让和为0的值。
res += map.getOrDefault(-i-j, 0);
}
}
return res;
}
}