leetcode350. 两个数组的交集 II
给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]
提示:
1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 1000
题目分析
题目描述
给定两个整数数组 nums1
和 nums2
,返回两个数组的交集。输出结果中的每个元素出现的次数,应与元素在两个数组中出现的次数一致。
算法分析
这个问题可以通过哈希表(无序映射)来解决。我们使用两个哈希表(p1
和 p2
)来存储两个数组中每个元素的出现次数。然后,我们遍历第一个哈希表,对于每个元素,如果它在第二个哈希表中也存在,则计算两个哈希表中该元素出现次数的最小值,并将其添加到结果数组中。
算法步骤
- 初始化两个哈希表
p1
和p2
。 - 遍历数组
nums1
,将每个元素及其出现次数存储在p1
中。 - 遍历数组
nums2
,将每个元素及其出现次数存储在p2
中。 - 初始化一个空向量
res
来存储结果。 - 遍历
p1
,对于每个元素k
:- 如果
p2
中包含k
,则找到p2
中k
的位置。 - 计算
p1
中k
的出现次数和p2
中k
的出现次数的最小值。 - 将
k
添加到res
中,次数为最小值。
- 如果
- 返回
res
。
算法流程
具体代码
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
unordered_map<int,int> p1;
unordered_map<int,int> p2;
for(int i=0;i<nums1.size();i++)
{
p1[nums1[i]]++;
}
for(int i=0;i<nums2.size();i++)
{
p2[nums2[i]]++;
}
vector<int> res;
for(auto k:p1)
{
if(p2.count(k.first))
{
auto t=p2.find(k.first);
int p1size=k.second;
int p2size=t->second;
int size=min(p1size,p2size);
for(int j=0;j<size;j++)
{
res.push_back(k.first);
}
}
}
return res;
}
};
算法分析
复杂度分析
- 时间复杂度:O(m+n),其中 m 和 n 分别是两个数组的长度。我们只需要遍历两个数组一次。
- 空间复杂度:O(m+n),我们需要存储两个数组的元素及其出现次数,这取决于数组的长度。
易错点
- 在初始化两个无序映射时,确保正确地存储每个元素及其出现的次数。
- 在比较两个映射中的元素时,确保正确地使用
count
函数。 - 在计算最小出现次数时,确保正确地使用
min
函数。
注意事项
- 确保在遍历数组时不要超出数组的边界。
- 在处理映射时,确保不会覆盖任何元素。