Swift 实战:秒算两个数组的交集(LeetCode 349)
文章目录
- 摘要
- 描述
- 题解答案
- 题解代码分析
- Swift 解法代码
- 代码详解
- 示例测试及结果
- 时间复杂度
- 空间复杂度
- 总结
摘要
两个数组取交集,看起来是个特别日常的操作,对吧?比如你想找出两个用户列表中共同的朋友,或者想知道两个商品集合里有什么是重复的。
但是在工程中,如果数据量稍微一大,写得不够高效就可能拖慢整个功能的响应速度。
今天我们就用 Swift 来实现 LeetCode 349 这道题,聊聊如何用集合(Set)这种数据结构,把交集运算写得又快又干净,还能直接放到你的项目里用。
描述
题目要求:
给定两个数组 nums1
和 nums2
,返回它们的交集,且结果中的每个元素必须是唯一的。输出顺序可以随意。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
解释:[4,9] 也是可行的
约束条件:
- 1 <= nums1.length, nums2.length <= 1000
- 0 <= nums1[i], nums2[i] <= 1000
题解答案
最直接的想法是:
- 把一个数组存进集合(Set),这样查找的时间复杂度是 O(1);
- 遍历另一个数组,把存在于集合中的元素加入结果集合;
- 最后返回结果集合转换成数组。
为什么用集合(Set)?
- 因为 Set 会自动去重,不用手动检查重复值;
- 查找元素是否存在的时间复杂度是 O(1);
- 语法简洁,非常适合这种“唯一元素+快速查找”的场景。
题解代码分析
Swift 解法代码
class Solution {func intersection(_ nums1: [Int], _ nums2: [Int]) -> [Int] {let set1 = Set(nums1)let set2 = Set(nums2)let result = set1.intersection(set2)return Array(result)}
}
代码详解
let set1 = Set(nums1)
let set2 = Set(nums2)
这两行把两个数组都转成集合,自动去重,同时提高查找速度。
let result = set1.intersection(set2)
Swift 的 Set
自带 intersection
方法,直接返回两个集合的交集,不需要写循环。
return Array(result)
题目要求返回数组,所以最后转回 Array
。
这种写法简洁到极致,并且底层性能很高,因为 Swift 的 Set 是基于哈希表实现的。
示例测试及结果
我们来跑一下实际例子,顺便做成一个可以直接运行的 Demo。
// Demo 主程序
let solution = Solution()let nums1 = [1,2,2,1]
let nums2 = [2,2]
print("交集结果 1:", solution.intersection(nums1, nums2))let nums3 = [4,9,5]
let nums4 = [9,4,9,8,4]
print("交集结果 2:", solution.intersection(nums3, nums4))
输出结果:
交集结果 1: [2]
交集结果 2: [9, 4]
结果与题目要求一致,而且你会发现代码运行非常快,即使数据量大一些也不会卡顿。
时间复杂度
- 转换为 Set:O(n) + O(m),n 和 m 分别是两个数组的长度;
- 求交集:O(min(n, m));
- 总体时间复杂度:O(n + m)
相比用双重循环的 O(n*m) 暴力解法,这种方式快太多。
空间复杂度
- 需要两个集合来存储 nums1 和 nums2:O(n + m);
- 结果集合也需要额外空间(但一般远小于输入数组总长度);
- 总体空间复杂度:O(n + m)
在可接受的范围内换来了速度上的提升。
总结
这道题是集合操作的经典应用:
- 利用
Set
自动去重 + 快速查找的特性,几行代码就能高效完成交集计算; - 时间复杂度直接降到 O(n + m),适合在用户量或数据量很大的情况下使用;
- 在实际项目里,比如“找出两个用户群的共同好友”、“获取两个商品清单的重复商品”都可以用同样思路。
如果你在 Swift 项目中经常遇到集合相关运算,不妨熟悉一下 intersection
、union
、subtracting
这些方法,很多需求几行就搞定。