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
-
示例一: 輸入: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 示例二: 輸入:nums1 = [0], nums2 = [0], nums3 = [0], nums4 = [0] 輸出:1
提示:
n == nums1.length
n == nums2.length
n == nums3.length
n == nums4.length
1 <= n <= 200
-228 <= nums1[i], nums2[i], nums3[i], nums4[i] <= 228
【演算法設計思想】
- 預處理:
- 使用一個雜湊表(或字典)來儲存
nums1
和nums2
中所有可能的兩兩元素之和及其出現次數。 - 鍵為兩兩元素之和,值為該和出現的次數。
- 使用一個雜湊表(或字典)來儲存
- 查詢:
- 遍歷
nums3
和nums4
,對於每一對元素,計算其和的相反數。 - 檢查這個相反數是否存在於雜湊表中,如果存在,則將該和出現的次數累加到結果計數器中。
- 遍歷
【演算法描述】
C++:
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int, int> map; // 雜湊表,用於儲存 nums1 和 nums2 中所有可能的和及其出現次數
// 遍歷 nums1 和 nums2,計算每一對元素的和,並將和及其出現次數存入雜湊表
for (auto& elem1 : nums1) {
for (auto& elem2 : nums2) {
map[elem1 + elem2]++;
}
}
int count = 0; // 用於統計滿足條件的四元組數量
// 遍歷 nums3 和 nums4,計算每一對元素的和,並檢查 -(c + d) 是否在雜湊表中
for (auto& elem3 : nums3) {
for (auto& elem4 : nums4) {
// 計算 -(c + d)
int target = 0 - elem3 - elem4;
// 檢查 target 是否在雜湊表中
if (map.find(target) != map.end()) {
// 如果存在,將對應的出現次數加到 count 上
count += map[target];
}
}
}
return count; // 返回滿足條件的四元組數量
}
};
Java:
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
// 使用 HashMap 儲存 nums1 和 nums2 中所有可能的兩兩元素之和及其出現次數
HashMap<Integer, Integer> map = new HashMap<>();
// 初始化計數器,用於記錄滿足條件的四元組數量
int count = 0;
// 遍歷 nums1 和 nums2,計算每一對元素的和,並記錄在 HashMap 中
for (int i = 0; i < nums1.length; i++) {
for (int j = 0; j < nums2.length; j++) {
int sum = nums1[i] + nums2[j];
// 使用 getOrDefault 方法確保鍵不存在時初始化為0
map.put(sum, map.getOrDefault(sum, 0) + 1);
}
}
// 遍歷 nums3 和 nums4,尋找與之前儲存的和相加等於0的情況
for (int i = 0; i < nums3.length; i++) {
for (int j = 0; j < nums4.length; j++) {
int target = 0 - nums3[i] - nums4[j];
// 如果這個相反數存在於 HashMap 中,則說明找到了一組解
if (map.containsKey(target)) {
// 增加計數器,值為 HashMap 中該和出現的次數
count += map.get(target);
}
}
}
// 返回滿足條件的四元組數量
return count;
}
}
Python:
class Solution:
def fourSumCount(
self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]
) -> int:
# 使用字典來儲存 nums1 和 nums2 中所有可能的兩兩元素之和及其出現次數
dic = {}
# 遍歷 nums1 和 nums2,計算每一對元素的和,並記錄在字典中
for elem1 in nums1:
for elem2 in nums2:
# 使用 get 方法確保鍵不存在時初始化為0
dic[elem1 + elem2] = dic.get(elem1 + elem2, 0) + 1
# 初始化計數器,用於記錄滿足條件的四元組數量
count = 0
# 遍歷 nums3 和 nums4,尋找與之前儲存的和相加等於0的情況
for elem3 in nums3:
for elem4 in nums4:
# 計算需要找到的相反數
target = 0 - elem3 - elem4
# 如果這個相反數存在於字典中,則說明找到了一組解
if target in dic:
# 增加計數器,值為字典中該和出現的次數
count += dic[target]
# 返回滿足條件的四元組數量
return count