349. 两个数组的交集(力扣LeetCode)

文章目录

  • 349. 两个数组的交集
    • 题目描述
    • 数组解题
    • set容器解题
      • 该思路数组版解题

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] 也是可通过的

提示:

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

数组解题

思路是使用两个辅助数组 a 和 b 来跟踪每个数组中哪些数字出现过。由于题目提示中给出的数字范围是 0 <= nums1[i], nums2[i] <= 1000,这两个数组的大小被设置为1000,对应可能存在的最大数字。

代码中的第一个for循环遍历数组 nums1,并在辅助数组 a 中对应的位置标记为1,表示这个数字出现过。同样的方法也应用于 nums2 和辅助数组 b。

之后,使用第三个for循环检查 a 和 b 中的每一个元素。如果两个数组在同一个索引位置上都标记了1,则意味着该数字在两个输入数组中都出现过,即它们的交集,因此将其添加到结果向量 nums3 中。

最终,nums3 包含了所有在两个输入数组中都出现过的唯一数字,即它们的交集,这个向量将被作为结果返回。

这段代码的理论执行时间复杂度为 O(n),其中 n 是输入数组中元素个数的上限(这里是1000)。实际的时间复杂度取决于输入数组 nums1 和 nums2 的真实大小。空间复杂度是 O(m),其中 m 是可能的数字范围的上限(在这个例子中是1000)。

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        // 声明两个大小为1000的数组来记录两个输入数组中元素的存在情况
        // 初始化为0
        int a[1000] = {0}, b[1000] = {0};
        
        // 遍历第一个数组nums1
        for(int i = 0; i < nums1.size(); i++)
            // 将数组a对应位置标记为1,表示nums1中存在该元素
            a[nums1[i]] = 1;
        
        // 遍历第二个数组nums2
        for(int i = 0; i < nums2.size(); i++)
            // 将数组b对应位置标记为1,表示nums2中存在该元素
            b[nums2[i]] = 1;
        
        // 声明一个向量nums3,用于存储交集元素
        vector<int> nums3;
        
        // 遍历数组a和b
        for(int i = 0; i < 1000; i++) {
            // 如果某个元素在两个数组中都存在,则将其加入到nums3
            if(a[i] == 1 && b[i] == 1)
                nums3.push_back(i);
        }
        
        // 返回包含交集的向量
        return nums3;
    }
};

set容器解题

这道题目,主要要学会使用一种哈希数据结构:unordered_set,这个数据结构可以解决很多类似的问题。

注意题目特意说明:输出结果中的每个元素一定是唯一的,也就是说输出的结果的去重的, 同时可以不考虑输出结果的顺序

如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费。
此时就要使用另一种结构体了,set ,关于set,C++ 给提供了如下三种可用的数据结构:

  • std::set
  • std::multiset
  • std::unordered_set

std::set和std::multiset底层实现都是红黑树,std::unordered_set的底层实现是哈希表, 使用unordered_set 读写效率是最高的,并不需要对数据进行排序,而且还不要让数据重复,所以选择unordered_set。

思路如图所示:
在这里插入图片描述

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        // 使用 unordered_set 来存储最终的交集结果,unordered_set 自动去重
        unordered_set<int> result;

        // 将 nums1 转换成 unordered_set,以便快速查找
        // 这里通过范围构造函数直接将 nums1 中的所有元素初始化到 set 中
        unordered_set<int> num(nums1.begin(), nums1.end());

        // 遍历 nums2
        for(int n : nums2) {
            // 使用 find 方法检查当前元素 n 是否存在于 nums1 的集合中
            // 如果存在,则说明 n 是 nums1 和 nums2 的交集中的一个
            if(num.find(n) != num.end())
                // 将 n 插入结果集合中,如果 n 已经存在,则不会重复插入
                result.insert(n);
        }

        // 将最终的交集结果转换成 vector 并返回
        // 这里也是通过范围构造函数,将 result 集合中的所有元素初始化到新的 vector 中
        return vector<int> (result.begin(), result.end());
    }
};

  • set.find() ,返回给定值值得定位器,如果没找到则返回end()。
if(num.find(n) != num.end())//只要不等于end()就代表找到了

该思路数组版解题

代码的执行流程是这样的:

  1. 声明一个 unordered_set result,用于存储交集,且自动去重。
  2. 创建一个大小为 1000 的数组 a,用于标记 nums1 中出现的元素。这里假设元素值不会超过 1000,根据题目提示,这是一个安全的假设。
  3. 遍历 nums1,对于 nums1 中的每个元素,将 a 数组对应索引处的值设置为 1。
  4. 遍历 nums2,对于 nums2 中的每个元素,检查 a 数组中相同值的索引位置是否被标记为 1(也就是检查是否在 nums1 中出现过)。
  5. 如果检查结果为 true(即 a[n] 等于 1),则将 n 添加到 result 集合中。
  6. 最后,将 result 集合中的元素转换为 vector 并返回作为最终结果。
    由于 unordered_set 是基于哈希表的,因此插入和查找的平均时间复杂度是 O(1)。该算法的总体时间复杂度是 O(n + m),其中 n 和 m 分别是 nums1 和 nums2 的长度。空间复杂度是 O(n),其中 n 是两数组中不同元素的数量。
class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        // 创建一个 unordered_set 来存储交集的结果,自动去重保证元素唯一
        unordered_set<int> result;
        
        // 创建一个大小为1000的数组来记录元素是否存在于 nums1 中
        // 数组初始化为0,表示没有任何元素
        int a[1000] = {0};

        // 遍历 nums1,将存在的元素在数组 a 中对应位置标记为1
        for(int i = 0; i < nums1.size(); i++)
            a[nums1[i]] = 1;

        // 遍历 nums2
        for(int n : nums2) {
            // 如果当前元素在数组 a 中被标记为1(即出现在 nums1 中)
            // 则将其添加到结果集合中
            if(a[n] == 1)
                result.insert(n);
        }

        // 将 unordered_set 转换为 vector 并返回
        // 这里使用范围构造函数,将 result 中的所有元素初始化到新的 vector 中
        return vector<int>(result.begin(), result.end());
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/357346.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB知识点:创建MATLAB的脚本

​讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili 节选自第2章 在实际应用中&#xff0c;直接在命令行窗口中输…

Phoncent博客,探索Rie Kudan的GPT创作之举

近日&#xff0c;大家都在谈论日本作家Rie Kudan&#xff0c;她凭借其小说《东京共鸣塔》&#xff08;"Tokyo-to Dojo-to"&#xff09;荣获了日本极具声望的芥川奖。这本小说引起了广泛的讨论和思考&#xff0c;因为令人惊讶的是&#xff0c;Kudan在其中直接引用了人…

伊恩·斯图尔特《改变世界的17个方程》毕达哥拉斯定理笔记

它告诉我们什么&#xff1f; 直角三角形的三个边之间有什么关系。 为什么重要&#xff1f; 它提供了几何和代数之间的重要联系&#xff0c;使我们能够根据坐标计算距离。它也催生出了三角学。 它带来了什么&#xff1f; 测绘、导航&#xff0c;以及较近代出现的狭义和广义相对论…

solr的原理是什么

1 Java程序里如果有无限for循环的代码导致CPU负载超高&#xff0c;如何排查&#xff1f; 排查Java程序中由于无限循环导致的CPU负载过高的问题&#xff0c;可以按照以下步骤进行&#xff1a; 资源监控&#xff1a; 使用系统命令行工具&#xff08;如Linux上的top或htop&#xf…

Pytest 识别case规则

一、Python测试框架&#xff0c;主要特点有以下几点&#xff1a; 简单灵活&#xff0c;容易上手&#xff1b;支持参数化&#xff1b;能够支持简单的单元测试和复杂的功能测试&#xff0c;还可以用来做selenium/appnium等自动化测试、接口自动化测试&#xff08;pytestrequests…

JavaWeb中的Filter(过滤器)和 Listener(监听器)

提示&#xff1a;这两个东西听起来似乎很难&#xff0c;实际上是非常简单的&#xff0c;按照要求写就行了&#xff0c;一定不要被新名词给吓到了。 JavaWeb中的Filter&#xff08;过滤器&#xff09; 一、Filter&#xff08;过滤器&#xff09;1.如何编写 Filter2.Filter 中的细…

翻译: GPT-4 Vision征服LLM幻觉hallucinations 升级Streamlit六

GPT-4 Vision 系列: 翻译: GPT-4 with Vision 升级 Streamlit 应用程序的 7 种方式一翻译: GPT-4 with Vision 升级 Streamlit 应用程序的 7 种方式二翻译: GPT-4 Vision静态图表转换为动态数据可视化 升级Streamlit 三翻译: GPT-4 Vision从图像转换为完全可编辑的表格 升级St…

探索Pyecharts:绘制多彩日历图的艺术与技巧

Pyecharts绘制多种炫酷日历图参数说明代码实战 导言 在数据可视化领域&#xff0c;日历图是一种直观展示时间和数据关系的方式。Pyecharts是一个基于Echarts的Python库&#xff0c;可以方便地绘制各种图表&#xff0c;包括炫酷的日历图。本篇博客将介绍Pyecharts中绘制多种炫…

Maya---补洞 桥接 连接

14.maya常用命令4.补洞 桥接 连接_哔哩哔哩_bilibili 边模式下&#xff1a; shift右键--->填充洞 对象模式下&#xff0c;可一次填充多个洞 桥接 连接工具 ctrlshift右键

SNP干货分享:SAP数据脱敏的具体实施步骤

随着信息技术的飞速发展&#xff0c;大数据时代的到来使得数据成为国家经济、企业竞争力和个人隐私的重要载体。在这种背景下&#xff0c;数据安全问题日益凸显&#xff0c;各国政府纷纷出台相关法规以保护数据安全。我国也不断完善数据安全法规体系&#xff0c;以确保国家利益…

HCIA-Datacom实验指导手册:4.1 实验一:访问控制列表配置实验,fragment分片acl演示。

HCIA-Datacom实验指导手册:4.1 实验一:访问控制列表配置实验 一、实验介绍:二、实验拓扑:三、实验目的:四、配置步骤:步骤 1 掌握ACL的配置方法 配置方法步骤 2 掌握 ACL在接口下应用方法步骤 3 掌握 流量过滤 的基本方式步骤 4 掌握 禁止分片报文通过的方法验证五、结果…

Git怎样用?(下载到本地,和在本地初始化)

全局设置&#xff1a; 点击第二个 输入&#xff1a; 例如&#xff1b;邮箱是随意地 git config --global user.name "名字" git config --global user.email "邮箱" 获取git仓库 本地初始化&#xff1a; 创建仓库 右键第二个 输入 git init 克隆&#…

Redis(九)集群(cluster)

文章目录 概述作用1. redis集群的槽位slot2. redis集群的分片3. 第1,2点的优势&#xff1a;**最大优势&#xff0c;方便扩缩容和数据分派查找**4. slot槽位映射&#xff0c;一般业界有3种解决方案第一种&#xff1a;哈希取余分区第二种&#xff1a;一致性哈希算法分区第三种&am…

U-Boot学习(6):初始化之_main函数源码分析

在上一节系统初始化之start.S源码分析详解中&#xff0c;我们分析了上电后的代码执行流程&#xff0c;实际上就是对系统特权模式、CP15、向量表等进行配置。最后一步就是进入_main函数了&#xff0c;这个就是U-Boot的主程序了&#xff0c;它完成了对系统内存、堆栈、全局结构体…

TensorFlow2实战-系列教程7:TFRecords数据源制作1

&#x1f9e1;&#x1f49b;&#x1f49a;TensorFlow2实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Jupyter Notebook中进行 本篇文章配套的代码资源已经上传 1、TFRecords 在训练过程中&#xff0c;基本都是使用GPU来计算&#xff0c;但是取一个…

防火墙知识普及详解,使用TOR Router把TOR作为默认网关,增加隐私/匿名性

防火墙知识普及详解,使用TOR Router把TOR作为默认网关,增加隐私/匿名性。 #################### 免责声明:工具本身并无好坏,希望大家以遵守《网络安全法》相关法律为前提来使用该工具,支持研究学习,切勿用于非法犯罪活动,对于恶意使用该工具造成的损失,和本人及开发者…

【ArcGIS微课1000例】0099:土地利用变化分析

本实验讲述在ArcGIS软件中基于两期土地利用数据,做土地利用变化分析。 文章目录 一、实验描述二、实验过程三、注意事项一、实验描述 对城市土地利用情况进行分析时,需要考虑不同时期土地利用图层在空间上的差异性,如农用地转建筑用地的空间变化。而该变化过程表现为各时期…

Glide完全解读

一&#xff0c;概述 glide作为android流行的图片加载框架&#xff0c;笔者认为有必要对此完全解读。glide提供了三级缓存、生命周期Destroy后自动移除缓存、自动适配ImageView&#xff0c;以及提供了各种对图片修饰的操作&#xff0c;如剪裁等。本文通过最简单的使用&#xff…

Spring Boot通过配置文件支持数据库自定义表名

直接上干货&#xff1a; 例如一个叫xxx的项目&#xff0c;yml文件里加上这段 xxxproject:db:xxxTable: xxx_dbname #自定义的数据库表名创一个Configuration类放表名和Mapper // XxxProjectAutoConfiguration.javaConfiguration MapperScan(basePackages "cn.com.xxxp…

PageHelper分页插件-以三层架构模型开发为例

文章目录 1、简介2、使用2.1、导入2.1.1、SpringBoot2.1.2、非SpringBoot 2.2、controller2.3、service2.4、mapper ​&#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;擅长web应用开发、…