力扣 349 两个数组的交集
给定两个数组 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 <= 10000 <= nums1[i], nums2[i] <= 1000
一. 哈希 unordered_set
首先拆解题目要求:
- 重复数字只保留一份
- 输出不要求有序
- 只需要存单个数值
分析各哈希容器的特点:
| 容器 | 底层结构 | 存储形式 | 增删查平均时间复杂度 | 是否有序 |
|---|---|---|---|---|
| unordered_set | 哈希表 | 单值 | O(1) | 无序 |
| set | 红黑树 | 单值 | O(log n) | 自动升序 |
| unordered_map | 哈希表 | key-value 键值对 | O(1) | 无序 |
| map | 红黑树 | key-value 键值对 | O(log n) | 自动升序 |
根据题目要求 单值无序 可快速判断出使用 unordered_set 为四种容器里面最优解。
✅利用 unordered_set 符合力扣格式的代码:
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());
for (int num : nums2) {
if (nums_set.find(num) != nums_set.end()) {
result_set.insert(num);
}
}
return vector<int>(result_set.begin(), result_set.end());
}
};
核心思路:
nums_set(nums1.begin(), nums1.end()),将nums1全部放入unordered_set,自动剔除nums1内部重复元素for (int num : nums2),for 循环 依次取出nums2中每一个元素,赋值给临时变量numif (nums_set.find(num) != nums_set.end())判断当前num是否同时存在于num1数组,核心原理是nums_set.find(num)表示在集合里搜寻num,找到则返回指向该元素的迭代器;找不到则返回nums_set.end(),因此!= end()等价于找到了result_set.insert(num)表示将符合if条件的元素插入结果集合中,如果已经存在也不会报错,因为unordered_set会自动去重return vector<int>(result_set.begin(), result_set.end())把存好交集元素的集合,转换成数组格式返回给判题系统
简单思路如下图所示:
- 时间复杂度: O(n + m) m 是最后要把 set转成vector
- 空间复杂度: O(n)
二. 哈希 数组
当题目确定了 数据范围 时就可以考虑使用数组来解答,例如本题给出:
1 <= nums1.length, nums2.length <= 10000 <= nums1[i], nums2[i] <= 1000
因此可以根据范围设定一个哈希数组,大小可定为 1005
✅利用数组符合力扣格式的代码:
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int>result_set;
int hash[1005] = {0};
for(int num : nums1){
hash[num] = 1;
}
for(int num : nums2){
if(hash[num] == 1){
result_set.insert(num);
}
}
return vector<int>(result_set.begin(), result_set.end());
}
};
核心思路是 nums1 每出现一个元素,哈希数组对应索引处值便赋为一,然后遍历 nums2,如果其中某值对应索引值处值为一,说明该值在 nums1 和 nums2 中均出现过,则将其插入到 result_set 中,最后将形式转换成符合条件的形式。
- 时间复杂度: O(m + n)
- 空间复杂度: O(n)