454_四数相加Ii

zeta186012 / 2024-10-13 / 原文

454_四数相加Ii

【问题描述】

给你四个整数数组 nums1nums2nums3nums4 ,数组长度都是 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

【算法设计思想】

  1. 预处理
    • 使用一个哈希表(或字典)来存储 nums1nums2 中所有可能的两两元素之和及其出现次数。
    • 键为两两元素之和,值为该和出现的次数。
  2. 查找
    • 遍历 nums3nums4,对于每一对元素,计算其和的相反数。
    • 检查这个相反数是否存在于哈希表中,如果存在,则将该和出现的次数累加到结果计数器中。

【算法描述】

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