力扣刷题 349.两个数组的交集

目录

题干

数据结构

解题思路


题干

给定两个数组 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] 也是可通过的

数据结构(set)

这道题也是用到了哈希表的思想,不过这次使用的数据结构是set

set是C++标准模板库(STL)中提供的一种容器,它实现了数学上的集合概念,即集合中的元素是唯一的,每个元素在集合中只出现一次。set的内部实现通常是基于红黑树,这是一种自平衡的二叉查找树,可以保证元素的有序性和高效的查找、插入和删除操作。

以下是set的一些主要特点:

  • 唯一性:set中不允许有重复的元素,每个元素都是唯一的。
  • 有序性:set中的元素会根据元素的值自动排序,保持一定的顺序。
  • 高效性:由于内部实现是红黑树,set提供了对数级别的查找、插入和删除操作。
  • 支持的操作:set支持一系列的操作,如判断元素是否存在、插入新元素、删除元素等。

总的来说,set是一个非常有用的工具,特别是在需要快速检索元素的情况下。


由于题目中没有要求元素的值有顺序,所以这里我们使用的是无序set,即unordered_set

与set不同,unordered_set内部实现是基于哈希表的,而不是红黑树。因此,它不保证元素的顺序,并且元素的存储位置是根据元素的哈希值决定的。

以下是unordered_set的一些主要特点:

  • 唯一性:unordered_set中不允许有重复的元素,每个元素都是唯一的。
  • 无序性:由于使用哈希表进行存储,unordered_set中的元素没有固定的顺序。
  • 高效性:由于哈希表的查找、插入和删除操作的平均时间复杂度为常数级别O(1),所以unordered_set提供了高效的性能。
  • 支持的操作:unordered_set支持一系列的操作,如判断元素是否存在、插入新元素、删除元素等。

总的来说,unordered_set是一种非常快速且高效的数据结构,适用于需要快速检索元素的场景,但不需要元素有序的情况。

以下是本题中要使用到的unordered_set的用法:

  1. 创建unordered_set对象:可以使用以下方式创建一个空的unordered_set对象:

    std::unordered_set<int> mySet;
  2. 插入元素:使用insert()函数将元素插入到unordered_set中:

    mySet.insert(42);
  3. 查找元素:可以使用find()函数来查找元素是否存在于unordered_set中:

    if (mySet.find(42) != mySet.end()) { // 元素存在 } else { // 元素不存在 }

           如果存在,返回指向该元素的迭代器;如果不存在,返回指向集合末尾的迭代器。


解题思路

整体的思路是将数组1的所有元素放到以set为数据结构的哈希表中,然后遍历数组2中的元素,与哈希表中的key对照,如果有相等的值就把该值放入结果set中。

完整代码如下:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
     unordered_set<int> result_set;
     unordered_set<int> num_set(nums1.begin(),nums1.end());
     for(int num : nums2){
        if(num_set.find(num) != num_set.end())
           result_set.insert(num);
     }
    return vector<int> (result_set.begin(),result_set.end());    
    }
};

这一道题也牵涉到了许多c++的用法

unordered_set<int> nums_set(nums1.begin(), nums1.end());

这段代码创建了一个名为nums_set的无序集合,并将nums1向量中的元素插入到该集合中。

(nums1.begin(), nums1.end()) 是一个范围表达式,它指定了要插入到集合中的元素范围。这里使用了nums1向量的起始迭代器和结束迭代器来定义范围。

 for (int num : nums2)

这段代码是一个基于范围的for循环,用于遍历nums2向量中的每个元素。

(int num : nums2) 是范围表达式,它定义了要遍历的元素和容器。这里使用了C++11引入的范围for循环语法。

int num 是循环变量,表示每次迭代时从nums2中取出的元素。

nums2 是要遍历的容器,即包含整数元素的向量。

因此,这段代码的作用是在每次迭代中,将nums2向量中的一个元素赋值给变量num,然后执行循环体内的代码。

return vector<int> (result_set.begin(),result_set.end());

这段代码的作用是将一个集合(result_set)转换为一个整数向量(vector)。

result_set.begin() 返回指向集合中第一个元素的迭代器。

result_set.end() 返回指向集合中最后一个元素之后的迭代器。

vector<int>(result_set.begin(), result_set.end()) 使用这两个迭代器作为参数,创建一个新的整数向量,并将集合中的元素复制到该向量中。

因此,这段代码的作用是将集合中的元素复制到一个新的整数向量中,并返回该向量。


数据结构(数组)

本题后面力扣改了题目描述和后台测试数据,增添了数值范围:

  • 1 <= nums1.length, nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 1000

所以我们也可以使用数组来做哈希表, 因为数组都是 1000以内的。

这里提一句数组相比于set的优点,因为直接使用set 不仅占用空间比数组大,而且速度要比数组慢,set把数值映射到key上都要做hash计算的,因此在遇到数据量较大的情况下,如果能用数组肯定是会节约不少时间的。

以下是完整代码:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result_set; /
        int hash[1005] = {0}; 
        for (int num : nums1) { 
            hash[num] = 1;
        }
        for (int num : nums2) { 
            if (hash[num] == 1) {
                result_set.insert(num);
            }
        }
        return vector<int>(result_set.begin(), result_set.end());
    }
};

  • 27
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值