【LeetCode349. 两个数组的交集】——数组型哈希表,set型哈希表

349. 两个数组的交集

给定两个数组 nums1nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序

示例 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 <= 1000
  • 0 <= nums1[i], nums2[i] <= 1000

思考:

本题乍一看,与之前的1002. 查找共用字符十分相似,不同之处有两点:一是本题输出的结果不能重复,每个元素都要求是唯一的,二是本题的数组中不再是字符,二是数字,而数字的取值范围则是远大于1002题中的26个字符的。

当然,本题给出了提示,给定了数字的取值范围,所以我们仍然可以选用数组型哈希表进行求解。求解方式就与1002十分相似(1条消息) 【LeetCode1002. 查找共用字符】——数组型哈希表_一粒蛋TT的博客-CSDN博客

但是由于这么做会产生极大的空间浪费,而且也有可能遇到数字取值范围不确定的情况,这个时候,我们就可以选用一种全新的哈希表类型,set哈希表进行求解。

数组型哈希表:

数组型哈希表是通过定义两个大小为1001的数组,对每个元素的出现次数进行记录,进而求解:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        vector<int> result;//定义结果数组

        //考虑空数组情况
        if (nums1.size() == 0 || nums2.size() == 0)
        {
            return result;
        }

        int hash1[1001] = { 0 };
        int hash2[1001] = { 0 };
        //遍历记录哈希表
        for (int i = 0; i < nums1.size(); i++)
        {
            hash1[nums1[i]]++;
        }
        for (int i = 0; i < nums2.size(); i++)
        {
            hash2[nums2[i]]++;
        }
        //取两者最小值
        for (int k = 0; k < 1001; k++)
        {
            hash1[k] = min(hash1[k], hash2[k]);
        }
        //与0比较进行输出
        for (int i = 0; i < 1001; i++)
        {
            if (hash1[i] != 0)
            {
                result.push_back(i);
            }
        }
        return result;

    }
};

set哈希表:

set哈希表的使用就比较简便,利用了unordered_set容器,可以大大节省空间。当哈希值比较少,而且分散,跨度大时,很适合用这种形式的哈希表。

然而set哈希表也有其缺点,不仅占用空间比数组大,而且速度要比数组慢。

class Solution2 {
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) {
            // 发现nums2的元素 在nums_set里又出现过
            if (nums_set.find(num) != nums_set.end()) {
                result_set.insert(num);
            }
        }
        return vector<int>(result_set.begin(), result_set.end());
    }
};

其中使用到了set容器中的find函数:

  • find(key); //查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();

也使用到了C++11的新特性,即

for (int num : nums2) 

等价于:

int num;
for(int i=0;i<num2.length;i++)
{
num=nums2[i];
}

参考:

代码随想录
范围for循环

往期回顾:
LeetCode1002. 查找共用字符
LeetCode142. 环形链表 II
面试题 02.07. 链表相交
LeetCode19. 删除链表的倒数第 N 个结点
LeetCode24. 两两交换链表中的节点
LeetCode206. 反转链表
LeetCode707.设计链表
LeetCode203.移除链表元素
LeetCode54. 螺旋矩阵
LeetCode59.螺旋矩阵II
LeetCode977.有序数组的平方
LeetCode844.比较含退格的字符串
LeetCode283.移动零
LeetCode27.移除元素
LeetCode26.删除有序数组中的重复项
LeetCode209.长度最小的子数组
LeetCode904. 水果成篮
LeetCode242.有效的字母异位词
LeetCode76.最小覆盖子串

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值