Swift — LeetCode — 两个数组的交集 II
我正在参加“掘金·帆船计划”
话题
给你两个整数数组 数字1
和 数字2
,请将两个数组的交集作为数组返回。返回结果中每个元素的出现次数应与该元素在两个数组中出现的次数相同(如果出现次数不一致,则考虑较小的值)。输出结果的顺序可以忽略。
示例 1:
- 进入:
nums1 = [1,2,2,1],nums2 = [2,2]
- 输出:
[2,2]
示例 2:
- 进入:
nums1 = [4,9,5],nums2 = [9,4,9,8,4]
- 输出:
[4,9]
方法一:哈希表
想法和解决方案
由于相同的数字可能在两个数组中出现多次,因此需要一个哈希表来存储每个数字的出现次数。对于一个数字,相交中出现的次数等于两个数组中该数字的最小出现次数。
首先遍历第一个数组,并记录第一个数组中的每个数以及对应的哈希表中出现的次数,然后遍历第二个数组,对于第二个数组中的每个数,如果哈希表中存在该数哈希表,将数字添加到答案中并减少数字在哈希表中的出现次数。
为了降低空间复杂度,先遍历较短的数组并将每个数和对应的出现次数记录在哈希表中,再遍历较长的数组得到交集。
代码
类解决方案{
func intersect(_ nums1: [ Int], _ nums2: [ Int]) -> [ Int] {
如果 nums1.count > nums2.count {
返回相交(nums2,nums1)
}
var map: [ Int : Int] = [:]
对于 nums1 中的 num {
让计数: Int = (map[num] ?? 0) + 1
地图[数字] = 计数
}
var 交点:[Int] = []
对于 nums2 中的 num {
让计数: Int = map[num] ?? 0
如果计数 > 0 {
交叉点.追加(数量)
地图[数字] = 计数 - 1
}
}
返回路口
}
}
复制代码
复杂性分析
- 时间复杂度:
- O ( m + n ) O(m+n)
- O ( m + n ) ,in
- 毫米
- 米和
- nn
- n 分别是两个数组的长度。需要遍历两个数组并对哈希表进行操作,哈希表操作的时间复杂度为
- O (1) O(1)
- O ( 1 ) ,因此总时间复杂度与两个数组的长度之和呈线性关系。
- 空间复杂度:
- O ( min ( m , n ) ) O(min(m,n))
- O ( 分钟 ( 米 , n ) ) , 在
- 毫米
- 米和
- nn
- n 分别是两个数组的长度。哈希表操作是在较短的数组上进行的,哈希表的大小不会超过较短数组的长度。为返回值创建一个数组
- 交叉路口
- 交集,其长度是较短数组的长度。
方法二:排序+双指针
想法和解决方案
如果对两个数组进行了排序,可以使用双指针的方法得到两个数组的交集。
首先对两个数组进行排序,然后使用两个指针遍历两个数组。
最初,两个指针分别指向两个数组的头部。每次比较两个指针所指向的两个数组中的数字,如果两个数字不相等,则指向较小数字的指针右移一位,如果两个数字相等,则将该数字添加到答案,两个指针右移一位。当至少一个指针超出数组边界时,遍历结束。
代码
类解决方案{
func intersect(_ nums1: [Int], _ nums2: [Int]) -> [Int] {
让 newNums1: [Int] = nums1.sorted()
让 newNums2: [Int] = nums2.sorted()
让 length1: Int = newNums1.count
让 length2: Int = newNums2.count
var 交点:[Int] = []
变量索引1 = 0
其中 index2 = 0
而 index1 < 长度 1 && 索引 2 < 长度 2 {
如果 newNums1 [index1] < newNums2 [index2] {
索引1 += 1
} else if newNums1 [index1] > newNums2 [index2] {
索引2 += 1
} 别的 {
intersection.append(newNums1 [index1])
索引1 += 1
索引2 += 1
}
}
返回路口
}
}
复制代码
复杂性分析
- 时间复杂度:
- O ( m log m + n log n ) O(m \log m+n \log n)
- O ( m lo gm + n lo gn ) ,in
- 毫米
- 米和
- nn
- n 分别是两个数组的长度。对两个数组进行排序的时间复杂度为
- O ( m log m + n log n ) O(m \log m+n \log n)
- O ( m lo gm + n lo gn ) ,遍历两个数组的时间复杂度为
- O ( m + n ) O(m+n)
- O ( m + n ) ,所以总时间复杂度为
- O ( m log m + n log n ) O(m \log m+n \log n)
- 从 (m lo gm + n lo gn)。
- 空间复杂度:
- O ( min ( m , n ) ) O(\min(m,n))
- O ( 分钟 ( 米 , n ) ) , 在
- 毫米
- 米和
- nn
- n 分别是两个数组的长度。为返回值创建一个数组
路口
,其长度是较短数组的长度。但在C++
,我们可以直接创建一个向量
,不需要将答案临时存储在一个额外的数组中,所以这个实现的空间复杂度是 - O (1) O(1)
- O(1)。
结语
如果
nums2\textit{nums}_2
nums 2 元素存储在磁盘上,磁盘内存有限,不能一次将所有元素加载到内存中。那么就不可能有效地
nums2\textit{nums}_2
nums 2 进行排序,所以建议使用方法一而不是方法二。在方法一中,
nums2\textit{nums}_2
nums 2 只与查询操作有关,所以每次读
nums2\textit{nums}_2
nums 2 可以完成部分数据的输入和处理。
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议。转载请附上原
这篇文章的链接: https://homecpp.art/1021/9737/1057
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明