Swift 数据结构与算法(34) + Leetcode[454. 四数相加 II(哈希表)

63 阅读5分钟

Swift 数据结构与算法( ) + Leetcode 掘金 #日新计划更文活动

题目

454. 四数相加 II

给你四个整数数组 nums1nums2nums3 和 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

示例 2:

输入: 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
class Solution {
    func fourSumCount(_ nums1: [Int], _ nums2: [Int], _ nums3: [Int], _ nums4: [Int]) -> Int {

    }
}

解题思路🙋🏻‍ ♀️

刚刚搞完三数之和... 用双指针搞... 又来四数之和...

这题看的我有点吐了... 没有思路... 暴力破解先来一波 4 for 循环.

这题就这么算了吧..... . . . 是肯定不行了

返回参数是 Int 类型, 所以不需要我们找出完整的数值, 只要有多少组就行.

重点

本题其实是将问题分解为 两个两数之和的问题

  1. 使用哈希表存储两数之和:首先,我们可以计算 nums1nums2 中所有两数之和,并将结果存储到一个哈希表中。哈希表的键是两数之和,值是这样的和出现的次数。
  2. 查找目标和的补数:接着,对于 nums3nums4 中的每一对数字,计算其和,然后查找哈希表中是否存在这个和的补数。如果存在,那么就找到了一个满足条件的组合。
  3. 统计满足条件的组合的数量:对于 nums3nums4 中的每一对数字,查找哈希表中其和的补数出现的次数,并将这些次数累加起来,得到的结果就是满足条件的组合的数量。

为啥是 nums1 + numbs2, nums3 和 nums4, 不能 nums1 + nums4 吗?

都可以哈!

只是方便描述和理解。实际上,任何两个数组组合都可以。只要你固定了两个数组来计算两数之和并存储到哈希表中,然后使用另外两个数组的数字来查找哈希表,就可以得到答案。

边界思考🤔

代码

for item4 in nums4 {

时空复杂度分析

时间复杂度

  • 第一步需要 O(n2) 的时间,因为需要对 nums1nums2 中的每一对数字计算两数之和。
  • 第二步也需要 O(n2) 的时间,因为需要对 nums3nums4 中的每一对数字计算两数之和,并在哈希表中查找其补数。
  • 所以总的时间复杂度是 O(n2)。

空间复杂度

  • 需要一个哈希表来存储两数之和,所以空间复杂度是 O(n2)。

错误与反思

  1. 首先构建一个字典来存储 nums1nums2 的元素之和及其出现的次数。
  2. 然后,遍历 nums3nums4 的元素,查找其和的相反数是否在之前的字典中。

经过检查,代码本身没有明显的错误,它应该可以正确地返回答案。

然而,对于这种问题,可能的错误或陷阱包括:

  1. 字典的使用:在更新字典时,必须确保正确地更新每个和的出现次数。如果不注意,可能会遗漏某些和或错误地计算它们的次数。
  2. 目标值的计算:在查找 nums3nums4 的和时,需要确保查找的是其和的相反数,即 -newItem。这是因为要找的是和为零的四个数。
  3. 重复的处理:由于题目要求计算所有可能的组合数(而不是唯一的组合),所以在这个问题中我们不需要担心重复的组合。但在其他类似问题中,需要确保不重复地添加解决方案。

为了避免此类问题中的错误,以下是一些建议:

  1. 充分理解问题:确保你完全理解了问题的需求和约束条件。
  2. 小步前进:不要试图一次性完成整个解决方案。首先解决一个部分,然后测试它,确保它的工作方式如你所预期。
  3. 使用测试用例:经常测试你的代码,特别是对于边界情况和可能的错误来源。

概念

使用场景与应用

这道题目主要涉及以下概念:

  1. 哈希表:使用哈希表存储某种信息,以便后续的快速查找。
  2. 双重循环:对两个数组进行组合并生成新的数据。
  3. 和为特定值的组合查找:这是一个常见的模式,需要在数组中找到和为特定值的组合。

实际应用场景:

  1. 数据库查询优化:在实际的数据库查询中,我们经常需要对多个数据集进行联接操作。哈希表可以被用来优化这些联接操作,使得查询速度更快。
  2. 缓存:哈希表是实现缓存的基础数据结构,例如Redis就是基于哈希表的内存数据结构存储。

iOS app 开发的实际使用场景:

  1. 查找重复的照片:在照片应用中,可以使用哈希表存储每张照片的哈希值,以便快速地找到重复的照片。
  2. 快速查找联系人:在联系人应用中,可以使用哈希表按名字存储联系人信息,从而实现快速的查找功能。
  3. 数据同步:在多设备同步应用数据时,可以使用哈希表对比本地数据和服务器数据的差异,从而只同步差异部分的数据。