LeetCode 350. 两个数组的交集 II

原题链接如下:
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 的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
    不能添加所有元素到内存中,因此我们不能采用哈希表的办法,只能采用排序双指针的办法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值