【LeetCode454】四数相加

题目描述

给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:

0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

思路与算法

将四数之和问题拆分为两部分,将问题规模降低到两个两数之和的问题,利用分治思想降低复杂度。
用字典记录所有 sum_ab 出现的次数,这样对于每个 sum_cd,可以 O(1) 时间查找对应的 -sum_cd 出现了几次。
时间复杂度:O(n^2)(两重循环分别对两个数组组进行遍历)
空间复杂度:O(n^2)(哈希表中存储最多 O(n^2) 个不同的和)

代码

class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:

        # 自动初始化计数为0
        sumCount = defaultdict(int)

        # 统计所有来自 nums1 和 nums2 的数对之和
        # 遍历 nums1 和 nums2,计算所有可能的和 sum_ab = a + b,并使用字典记录每个和出现的次数。
        for a in nums1:
            for b in nums2:
                sum_ab = a + b
                sumCount[a+b] += 1
        
        count = 0
        # 统计所有来自 nums3 和 nums4 的数对之和
        for c in nums3:
            for d in nums4:
                sum_cd = c + d
                # 查找它们的相反数在上一组中出现的次数,累加起来即为满足条件的元组个数。
                count += sumCount.get(-sum_cd, 0)
        return count

总结

  1. dict.get(key, default) 用于在字典中查找 key 对应的值,如果不存在返回默认值 default。这在累加时非常方便。
  2. collections.defaultdict(int) 自动将不存在的键初始化为 0,避免在统计过程中需要额外判断键是否存在。
  3. 哈希表计数:使用字典记录某些值出现的次数,方便后续查找。典型应用于“两数之和”、“三数之和”、“四数之和”等问题。
  4. 分治思想其实也降低了时间复杂度。将高维问题拆分为低维问题(例如四重循环拆分为两个双重循环)是降低时间复杂度的常用技巧。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值