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
题目分析: 即存在四个相同长度的独立数组,每个数组中取一个元素进行相加,若和为0则满足条件,最后返回满足条件的组数sum值。
思路分析: 常规的思路便是嵌套循环,4个for嵌套再if但在判题时会超时。因此想下其他方法,进行题目分析可得到以下:
- 可见4个数组转换为两个各种存放相邻元素和的数组。即sumNums1存放的是nums1和nums2中的元素和,sumNums2存放的是nums3和nums4中的元素和。
- 求和后的数组即sumNums1和sumNums2中可能出现元素存在重复的情况,即相同元素的个数直接会影响到最终满足条件的组数sum。
思路分析的第二点中,发现求和后相同元素的个数会对最终结果产生影响,因此考虑使用Hash对其中一个sumNums进行存储,key为元素值,而value为该元素出现的个数,总的来说解决该问题分为以下几步:
1.相邻数组两两求和得到新的数组
2.将求和后的一个数组用Hash保存(key为元素值,value为该元素值出现的个数)
3.遍历另一个求和后的数组并进行条件判断
采用以上思路后,Hash的话采用HashMap.
import java.util.HashMap;
//leetcode submit region begin(Prohibit modification and deletion)
//
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
int sum = 0;
int []sumNums1 = new int[nums1.length * nums2.length];
int []sumNums2 = new int[nums3.length * nums4.length];
//HashMap存放的key-value很关键
//key为两数之和, value为两数之和的次数
HashMap<Integer,Integer> records = new HashMap<>();
int num = 0;
//1.赋值两两求和数组
for (int i = 0; i < nums1.length ; i++) {
for (int j = 0; j < nums2.length; j++) {
sumNums1[num++] = nums1[i] + nums2[j];
}
}
num = 0;
for (int i = 0; i < nums3.length ; i++) {
for (int j = 0; j < nums4.length; j++) {
sumNums2[num++] = nums3[i] + nums4[j];
}
}
//2. 其中一个数组放入Map, key为数组元素值,value为该元素个数
for (int i = 0; i < sumNums1.length; i++) {
records.put(sumNums1[i], records.getOrDefault(sumNums1[i], 0) + 1);
}
//3.遍历另一个求和后的数组并进行条件判断
for (int i = 0; i < sumNums2.length; i++) {
if (records.containsKey(0 - sumNums2[i])){
sum += records.get(0 - sumNums2[i]);
}
}
return sum;
}
}
//leetcode submit region end(Prohibit modification and deletion)