刷刷刷Day7| 454.四数相加II
454.四数相加II
LeetCode题目要求
给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:
- 0 <= i, j, k, l < n
- nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
示例 1:
输入:nums1 = [1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2]
输出:2
解释:
两个元组如下:
1. (0, 0, 0, 1) -> nums1[0] + nums2[0] + nums3[0] + nums4[1] = 1 + (-2) + (-1) + 2 = 0
2. (1, 1, 0, 0) -> nums1[1] + nums2[1] + nums3[0] + nums4[0] = 2 + (-1) + (-1) + 0 = 0
解题思路
- 暴力解决,需要四个循环嵌套,相当于做了穷举,时间复杂度是 O(nnn*n)
- 参考两数之和,借助 Map,将四个数组分成两两一组,相当于计算两数之和,整体时间复杂度降低为 O(n²)
上代码:
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
// 4 个数组,每个数组中选一个元素出来,然后相加,如果和为 0。有多少找多少
// 符合和为 0 的数量
int sum0Count = 0;
// 4 个数组的长度是相等的。这里直接取第一个数组的长度
int len = nums1.length;
// 类似两数之和,定义一个 Map,存储 nums1,nums2 穷举元素之和,及和对应的次数。
Map<Integer, Integer> map = new HashMap<>();
// 遍历 nums1, nums2, 计算元素的和并存储到 map 中
for (int n1 : nums1) {
for (int n2: nums2) {
int sum12 = n1 + n2;
map.merge(sum12, 1, Integer::sum);
}
}
// 遍历 nums3, nums4, 计算元素的和,并判断 map 中是否与之 之和 为 0 的元素
for (int n3 : nums3) {
for (int n4 : nums4) {
int sum34 = n3 + n4;
// 判断 map 中是否存在 0-sum34 的元素,因为我们要计算的是 4 个元素和为 0
if (map.containsKey(0-sum34)) {
// 存在时取这个 key 出现的次数,因为题目要求是计算次数
sum0Count += map.get(0-sum34);
}
}
}
return sum0Count;
}
}
重难点
执行时间复杂度,通过使用哈希表,将时间复杂度降低为 O(n²)
附:学习资料链接