原题链接如下:
350. 两个数组的交集 II
题解1(哈希表):
一看到重复元素,就想到了去重万能的哈希表,由于本题还有一个取较少次数的要求,故我们还需要一个属性来记录出现次数,因此我们采用拥有键值对的hashmap,用数字的值当成key,数字出现次数当成value。先将nums1数组中的元素添加到哈希表中,然后再遍历nums2,若之前的哈希表中已经含有该元素,则该数字添加进result的数组中,同时哈希表中该数字的value值-1,若某一数字的value值已经为0之后,即使哈希表中出现了这个数字,我们也不再把它加入到result数组中了(注意:这样做就能达到题目中所要求的考虑取出现次数较小的那个)
本题解中用到的unordered_map
相关参考链接:
(65条消息) C++ 中unordered_map的用法_snailme的博客-CSDN博客_unordered_map遍历
std::unordered_map::erase - cppreference.com
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
unordered_map<int,int>map;
for(int num:nums1){
//这一步是先将nums1中的元素情况添加到哈希表中
map[num]++;
}
vector<int> result;
for(int num:nums2){
//切记,c++中unordered_map查找元素是find或count这两个函数
if(map.find(num)!=map.end()){
//如果map里找得到这个元素,我们就加到结果数组里面去
result.push_back(num);//采用push_back函数从尾端插入,方便
map[num]--;
if(map[num] == 0){
map.erase(num);//map中采用erase来删除元素
}
}
}
return result;
}
};
执行用时:4 ms, 在所有 C++ 提交中击败了88.11%的用户
内存消耗:10.1 MB, 在所有 C++ 提交中击败了46.53%的用户
通过测试用例:56 / 56
观察官方哈希表的题解我发现,官方题解是将更短的nums数组加入map中,这样可以节省空间,降低空间复杂度,于是我添加了一行代码:
if(nums1.size()>nums2.size()){
//我们之前默认的是第一个参数的数组加入到map,若作为第一个参数的数组的长度更大,我们就调换一下实传递顺序
return intersect(nums2, nums1);
}
最后提交发现内存消耗并没有减少,本人知识有限,找不到原因,可能是测试用例中两个数组长度差距都不太大吧
题解2(排序后双指针):
说来惭愧,这个方法是我看到题目标签中有双指针才想到用这个方法,大致思路是先将两个数组从小到大排序,维护两个首先指向第一个元素的指针,分别指向nums1和nums2,如果两指针所指向的值相等,则将结果加入到results数组中;如果两个指针所指向的值不同,则值小的那个指针向右移动,直至有一方指针到达数组末尾。
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
vector<int>result;
int p1 = 0;
int p2 = 0;
//c++中的sort函数,终于算是用得熟练了一点
sort(nums1.begin(),nums1.end());
sort(nums2.begin(),nums2.end());
while(p1<=nums1.size()-1&&p2<=nums2.size()-1){
if(nums1[p1]==nums2[p2]){
result.push_back(nums1[p1]);
p1++,p2++;
}else if(nums1[p1]<nums2[p2]){
p1++;
}else {
p2++;
}
}
return result;
}
};
最后对于官方进阶三问:
进阶:
- 如果给定的数组已经排好序呢?你将如何优化你的算法?
已经排好序的话,由于我们解法一中的哈希表有空间复杂度的劣势,我们可以找一个时间复杂度差不多,但是空间复杂度更加占优的排序双指针法 - 如果 nums1 的大小比 nums2 小,哪种方法更优?
如果nums1比nums2小,用哈希表的方法,将nums1中的元素添加到哈希表中可能会好一些 - 如果 nums2 的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
不能添加所有元素到内存中,因此我们不能采用哈希表的办法,只能采用排序双指针的办法。