力扣第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
思路和解题方法
- 首先,我们定义了两个
unordered_set<int>
类型的变量:result_set
和nums_set
。其中,nums_set
用于存储nums1
中的元素,并通过将nums1
数组中的所有元素插入到集合中,实现了去除重复元素的功能。而result_set
则用于存储交集的结果。- 接下来,我们遍历
nums2
数组中的每个元素num
。对于每个元素num
,我们使用nums_set.find(num)
查找该元素是否在nums_set
中出现过。如果找到了,则说明该元素也存在于nums1
中,属于交集的一部分,因此将其添加到result_set
集合中。- 最后,我们使用
vector<int>(result_set.begin(), result_set.end())
将result_set
集合转换为一个vector
,并作为函数返回值,完成了求交集的操作。
复杂度
时间复杂度:
O(m+n)
其中 m 和 n 分别是 nums1 和 nums2 的长度。遍历 nums1 并将其插入到哈希表中的时间复杂度是 O(m),遍历 nums2 查找交集并插入结果集的时间复杂度是 O(n)。总体来说,时间复杂度为 O(m + n)。
空间复杂度
O(m)
其中 m 是 nums1 的长度。使用一个额外的哈希表来存储 nums1 中的元素,最坏情况下需要存储全部元素。因此,空间复杂度为 O(m)。
c++ 代码
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> result_set; // 存储交集结果的哈希集合
unordered_set<int> nums_set(nums1.begin(), nums1.end()); // 将 nums1 中的元素存储到哈希集合中
for (int num : nums2) { // 遍历 nums2 数组中的每个元素
if (nums_set.find(num) != nums_set.end()) { // 若该元素在 nums_set 中存在
result_set.insert(num); // 将其插入结果集中
}
}
return vector<int>(result_set.begin(), result_set.end()); // 将结果集转换为 vector 返回
}
};
set容器和哈希
C++ 标准库提供了多种容器供选择。其中包括 set
容器和哈希表(unordered_set
)。下面我们来解释一下它们的特点和用法。
1. Set 容器:
set
是一个有序集合容器,它维护了一组唯一的元素。这意味着在set
中不能存在重复的元素,并且元素按照自然顺序进行排序。如果需要自定义排序,可以通过提供比较函数或函数对象来实现。set
提供了高效地插入、删除和查找操作,其时间复杂度为 O(log n)。这是因为set
内部使用了平衡二叉搜索树(通常是红黑树)来组织元素。由于元素是有序的,set
还支持一些有关范围查找的操作,例如查找给定范围内的所有元素。- 使用
set
容器的一些常见用途包括去除重复元素、排序和查找唯一元素。
2. 哈希表(unordered_set):
- 哈希表(也称为散列表)是一种使用哈希函数将键映射到存储位置的数据结构。在 C++ 的标准库中,哈希表对应的容器是
unordered_set
。unordered_set
是一个无序集合容器,其中的元素是唯一的。它使用哈希函数来确定元素的存储位置,因此插入、删除和查找操作的时间复杂度通常是常数时间 O(1)。然而,在最坏的情况下(例如哈希函数导致大量冲突),时间复杂度可能会变为 O(n)。- 与
set
不同,unordered_set
不维护元素的顺序。这意味着在遍历时,并不能保证元素的顺序和插入的顺序一致。如果需要有序的集合,应该使用set
而不是unordered_set
。- 由于哈希表的特性,
unordered_set
在查找和去重方面非常高效。它适用于不需要有序元素的场景,例如统计元素出现次数、判断元素是否存在等。- 需要注意的是,
unordered_set
对象的元素类型必须支持哈希函数和相等运算符,或者自定义一个哈希函数和相等运算符以供使用。- 总结起来,
set
是有序的集合容器,适用于排序、去重及范围查找等场景;unordered_set
是无序的集合容器,适用于高效的插入、删除和查找操作。选择使用哪个容器要根据具体的需求和性能要求来决定。
额外知识
unordered_map
unordered_map
是 C++ 标准库中的一个哈希表容器,用于存储键值对。它提供了高效的插入、删除和查找操作,并且这些操作的时间复杂度通常是常数时间 O(1)。以下是关于 unordered_map
的一些重要特点和用法:
-
存储键值对:
unordered_map
存储了一系列键值对,每个键都唯一。键(key)和值(value)可以是任意类型的,只要满足特定要求(例如支持哈希函数和相等比较运算符)。插入新的键值对时,可以使用下标运算符[]
或insert()
函数。 -
哈希函数:
unordered_map
使用哈希函数将键映射到内部存储位置。哈希函数负责计算键的哈希值,然后将其转换为对应的存储索引。C++ 标准库已经提供了对许多常见类型的默认哈希函数,但你也可以自定义哈希函数来适应特定的键类型。 -
冲突解决: 在哈希表中,冲突指的是两个或多个键被映射到相同的存储索引。
unordered_map
使用拉链法来解决冲突。具体来说,每个存储索引都是一个链表,同一索引上的键值对通过链表连接在一起。当出现冲突时,新的键值对将插入到对应索引的链表中。 -
高效的操作:
unordered_map
提供了高效的操作,包括插入、删除和查找。这些操作的平均时间复杂度是常数时间 O(1),但在最坏情况下(例如存在大量冲突),时间复杂度可能会退化为线性时间 O(n)。因此,选择合适的哈希函数和控制冲突是确保性能的关键。 -
迭代器和范围遍历: 可以使用迭代器对
unordered_map
中的键值对进行遍历。迭代器提供了访问键和值的方法,可以通过递增迭代器来依次访问每个键值对。此外,unordered_map
也支持范围遍历,通过结合 C++11 的范围循环语法,可以方便地遍历所有键值对。
unordered_map
是很常用的容器之一,适用于需要根据键快速查找对应值的场景。它具有高效的操作,且允许自定义键类型和哈希函数。然而,需要注意的是,unordered_map
不保持键的插入顺序。如果需要有序的容器,应该考虑使用 map
容器。
unordered_set
unordered_set
是 C++ 标准库中的一个哈希表容器,用于存储唯一的元素。它提供了高效的插入、删除和查找操作,并且这些操作的时间复杂度通常是常数时间 O(1)。以下是一些关于 unordered_set
的重要特点和用法:
-
存储唯一元素:
unordered_set
存储了一组唯一的元素,每个元素都是独一无二的。它使用哈希函数将元素映射到内部存储位置,并使用拉链法解决冲突。在插入新元素时,会根据哈希函数计算元素的哈希值,然后将其插入到对应的存储索引位置。 -
哈希函数:
unordered_set
使用哈希函数将元素映射到内部存储位置。哈希函数负责计算元素的哈希值,然后将其转换为对应的存储索引。C++ 标准库已经提供了对许多常见类型的默认哈希函数,但你也可以自定义哈希函数来适应特定的元素类型。 -
冲突解决: 在哈希表中,冲突指的是两个或多个元素被映射到相同的存储索引。
unordered_set
使用拉链法来解决冲突。具体来说,每个存储索引都是一个链表,同一索引上的元素通过链表连接在一起。当出现冲突时,新的元素将插入到对应索引的链表中。 -
高效的操作:
unordered_set
提供了高效的插入、删除和查找操作。这些操作的平均时间复杂度是常数时间 O(1),但在最坏情况下(例如存在大量冲突),时间复杂度可能会退化为线性时间 O(n)。因此,选择合适的哈希函数和控制冲突是确保性能的关键。 -
迭代器和范围遍历: 可以使用迭代器对
unordered_set
中的元素进行遍历。迭代器提供了访问元素的方法,可以通过递增迭代器来依次访问每个元素。此外,unordered_set
也支持范围遍历,通过结合 C++11 的范围循环语法,可以方便地遍历所有元素。
unordered_set
是一个常用的容器,适用于需要高效去重和快速查找元素的场景。它具有高效的操作,且允许自定义元素类型和哈希函数。然而,需要注意的是,unordered_set
不保持元素的插入顺序。如果需要有序的容器,应该考虑使用 set
容器。
觉得有用的话可以点点赞,支持一下。
如果愿意的话关注一下。会对你有更多的帮助。
每天都会不定时更新哦 >人< 。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)