两个数组的交集
本节对应代码随想录中:代码随想录,讲解视频:学透哈希表,set使用有技巧!Leetcode:349. 两个数组的交集_哔哩哔哩_bilibili
习题
题目链接:349. 两个数组的交集 - 力扣(LeetCode)
给定两个数组 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] 也是可通过的
我的解法
这题我是用的上题进阶解法用到的 unordered_map,只不过由于取交集,如果有重复的只输出一次即可。所以我在存的时候让 nums1对应的次数都为1,遍历 nums2时,如果次数为1则 push_back 并且次数+1,这样就不会重复输出。
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_map<int, int> hash;
vector<int> res;
// 不同的数只放一次
for (int i = 0; i < nums1.size(); i++) {
hash[nums1[i]] = 1;
}
for (int i = 0; i < nums2.size(); i++) {
// 次数为1说明重叠,加1后后面就不会push_back同样的元素
if (hash[nums2[i]] == 1) {
res.push_back(nums2[i]);
hash[nums2[i]]++;
}
}
return res;
}
};
- 时间复杂度:O(m+n)。其中m为nums1的长度,n为nums2的长度。需要遍历两个数组来建立哈希表和查找重叠元素,时间复杂度为O(m+n)。
- 空间复杂度:O(min(m,n))。哈希表中最多存储 min(m,n)个不同的元素,因此空间复杂度为 O(min(m,n))。
set 解法
这道题由于去重,所以其实用 set 更合适。
代码随想录中用了两个 set,一个遍历 nums1,另一个存放结果(这样结果就会去重)。但其实只用一个 set 即可,用一个 set 遍历 nums1后,再去遍历 nums2时,判断元素是否出现,若出现则 push_back 并且 erase 即删除这个元素。这样例如示例1中后面即使有重复的2,但我们在遍历第一个2进行 push_back 后就将 set 中的2删除了,遇到第二个2的时候其实就是找不到的状态了,所以就不会重复输出。
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> nums_set(nums1.begin(), nums1.end());
vector<int> res;
for (int num : nums2) {
// 如果nums_set包含num,则num是交集之一,加入结果并从集合中删除num
if (nums_set.erase(num)) {
res.push_back(num);
}
}
return res;
}
};
- 时间复杂度:O(m+n)。其中m和n分别为nums1和nums2的长度。因为需要遍历nums1和nums2各一次,而unordered_set的查找和删除操作的时间复杂度都是常数级别的,所以总时间复杂度为O(m+n)。
- 空间复杂度:O(min(m,n))。其中m和n分别为nums1和nums2的长度。因为需要使用unordered_set存储nums1中的元素,所以空间复杂度取决于nums1和nums2中较小的那个。