Leetcode记录:350. 两个数组的交集 II

给定两个数组,编写一个函数来计算它们的交集。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]

说明:
输出结果中每个元素出现的次数,应与元素在两个数组中出现次数的最小值一致。
我们可以不考虑输出结果的顺序。
进阶:
如果给定的数组已经排好序呢?你将如何优化你的算法?
如果 nums1 的大小比 nums2 小很多,哪种方法更优?
如果 nums2 的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
来源:Leetcode

方法:
同样使用之前的哈希表方式,只是因为上个题目中有规定给定数组中数值的范围因此可以用指定长度的vector进行储存,这一次需要使用map容器进行遍历储存。
百度了一下map以及unordered_map的区别

map是一种有序的容器,底层是用红黑树实现的(什么是红黑树?),红黑树是一种自平衡的二叉树,可以保障最坏情况的运行时间,它可以做到O(logn)时间完成查找、插入、删除元素的操作。
unordered_map是一种无序的容器,底层是用哈希表实现的(哈希表-维基百科),哈希表最大的优点是把数据的查找和存储时间都大大降低。
关于它们的适用场景,在有顺序要求的场合,肯定是要用map的;如果我们只操作一次,为了保证最坏情况下的运行时间,最好也适用map;而如果是需要经常操作,map肯定是没有unordered_map快的。因此,除了有顺序要求和有单词操作时间要求的场景下用map,其他场景都使用unordered_map。
在这里插入图片描述

因此步骤是:
1.首先遍历短的vector,将键值对保存到unordered_map即哈希表中,数字的值作为键,而值为数字出现的个数。
2.然后接下来遍历长的vector,并在map中寻找是否存在匹配的键,如果有则将该值存入储存结果的vector中并讲map中对应的值-1,若值减为0则删除该键值对,这样当长的数组中若同样元素的个数多于短的数组,遍历到多的出来的元素时,将不会在map中找到匹配的键,从而保证了输出结果中每个元素出现的次数与元素在两个数组中出现次数的最小值一致。

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
    if(nums1.size()>nums2.size())
    {
        return intersect(nums2,nums1);  //题解中保证先遍历小的vector的方法
    }
    vector<int> result;
    unordered_map <int, int> m;
    for(int num:nums1)                        
    {
        m[num]++;                
    }
    for(int num:nums2)
    {
        if(m.count(num))
        {
            result.push_back(num);
            m[num]--;
            if(m[num]==0)
            {
                m.erase(num);
            }
        }
    }
    return result;

    }
};

接下来对于优化,如果是两个排序好的数组则采用双指针遍历更为便捷。若空间有限也应该采用上述哈希表方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值