349. 两个数组的交集 题解

题目描述:349. 两个数组的交集 - 力扣(LeetCode)

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

 方法一:

解题思路:

我们可以采用排序和双指针的方法来求两个数组的交集。

  1. 对两个输入数组 nums1nums2 进行排序,以便能够有效地在有序数组中查找交集元素。

  2. 初始化两个指针 ptr1ptr2,分别指向数组 nums1nums2 的起始位置。

  3. 创建一个结果数组,用于存储交集元素。同时,创建一个变量 count 用于记录结果数组中的元素个数。

  4. 开始循环遍历两个有序数组:

    • 比较 nums1[ptr1]nums2[ptr2]
    • 如果两个元素相等,则将这个元素添加到结果数组中,然后增加 ptr1ptr2
    • 如果 nums1[ptr1] 小于 nums2[ptr2],则增加 ptr1
    • 如果 nums1[ptr1] 大于 nums2[ptr2],则增加 ptr2
  5. 循环继续,直到任一指针达到其数组的末尾。

  6. 返回结果数组,同时更新 count 为结果数组中的元素个数。

代码:

// 比较函数,用于排序
int compare(const void *a, const void *b) {
    return (*(int *)a - *(int *)b);
}

int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {
    qsort(nums1, nums1Size, sizeof(int), compare);
    qsort(nums2, nums2Size, sizeof(int), compare);
    
    int *result = (int *)malloc(sizeof(int) * (nums1Size < nums2Size ? nums1Size : nums2Size));
    int count = 0;
    
    int i = 0, j = 0;
    while (i < nums1Size && j < nums2Size) {
        if (nums1[i] == nums2[j]) {
            // 避免重复添加相同元素
            if (count == 0 || nums1[i] != result[count - 1]) {
                result[count++] = nums1[i];
            }
            i++;
            j++;
        } else if (nums1[i] < nums2[j]) {
            i++;
        } else {
            j++;
        }
    }
    
    *returnSize = count;
    return result;
}

方法二:

解题思路:

利用哈希集合

  1. 初始化一个哈希集合,用于存储 nums1 数组中的元素。

  2. 遍历 nums1 数组,将其中的元素加入哈希集合中。

  3. 创建一个结果数组,用于存储交集元素。

  4. 遍历 nums2 数组,对于其中的每个元素,判断是否在哈希集合中出现:

    • 如果出现,则将该元素加入结果数组,并从哈希集合中移除,以避免重复添加相同元素。
  5. 返回结果数组。

代码:

typedef struct
{
    int *data;
    int size;
} HashSet;

// 初始化哈希集合
HashSet* initHashSet()
{
    HashSet* set = (HashSet*)malloc(sizeof(HashSet));
    set->data = (int *)calloc(1000, sizeof(int));  // 注意初始化一定要是0
    set->size = 0;
    return set;
}

// 将元素加入哈希集合
void addToHashSet(HashSet* set, int num)
{
    set->data[num] = 1;
    set->size++;
}

// 判断元素是否在哈希集合中
int isInHashSet(HashSet* set, int num)
{
    return set->data[num];
}

// 释放哈希开辟的内存
void freeHashSet(HashSet* set)
{
    free(set->data);
    free(set);
}


int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize)
{
    HashSet* set = initHashSet();
    // 将数组1中的元素添加到哈希集合中
    for(int i=0;i<nums1Size;i++)
    {
        addToHashSet(set, nums1[i]);
    }
    int* ret = (int*)malloc(sizeof(int)*(nums1Size<nums2Size?nums2Size:nums1Size));
    int count = 0;
    // 查询
    for(int i=0;i<nums2Size;i++)
    {
        if(isInHashSet(set, nums2[i]))
        {
            // 添加
            ret[count++] = nums2[i];
            set->data[nums2[i]] = 0; // 避免重复添加
        }
    }
    *returnSize = count;
    freeHashSet(set);
    return ret;
}

总结:

哈希集合方法:

  • 时间复杂度:O(m + n),其中 m 是 nums1 的长度,n 是 nums2 的长度。

    • 创建哈希集合需要 O(m) 的时间,因为需要将 nums1 中的元素加入集合。
    • 遍历 nums2 并检查元素是否在哈希集合中需要 O(n) 的时间。
    • 最终的结果遍历需要 O(min(m, n)) 的时间,其中 min(m, n) 是结果数组的长度。
  • 空间复杂度:O(m) 或 O(n),取决于 nums1 数组的大小。

    • 哈希集合需要存储 nums1 中的元素,因此需要 O(m) 的额外空间。

排序和双指针方法:

  • 时间复杂度:O(m * log m + n * log n + m + n),其中 m 是 nums1 的长度,n 是 nums2 的长度。

    • 排序 nums1nums2 需要 O(m * log m) 和 O(n * log n) 的时间。
    • 遍历两个有序数组需要 O(m + n) 的时间。
    • 最终的结果遍历需要 O(min(m, n)) 的时间。
  • 空间复杂度:O(1)。

    • 这种方法只使用了常量级的额外空间用于存储指针和计数。

总结起来,如果在意时间复杂度,当 mn 较小时,两种方法的时间复杂度都差不多,但哈希集合方法在一些特定情况下可能会稍微快一些。然而,如果在意空间复杂度,排序和双指针方法的空间复杂度更低。


本次内容到此结束了!如果你觉得这篇博客对你有帮助的话 ,希望你能够给我点个赞,鼓励一下我。感谢感谢……

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

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

相关文章

时序数据库influxdb笔记

官方资料 https://docs.influxdata.com/influxdb/v2.7/install/?tLinux https://www.influxdata.com/influxdb/ 安装 1、linux平台下 1&#xff09;下载 2&#xff09;解压 3&#xff09;添加账户&#xff08; adduser influx&#xff09; 4&#xff09;设置目录权限 5…

缺少或找不到vcruntime140_1.dll的解决方法

某天&#xff0c;当我准备打开电脑上的一个应用程序时&#xff0c;突然收到一个错误提示&#xff0c;显示缺少了vcruntime140_1.dll文件。这个文件是一个重要的系统组件&#xff0c;它的丢失导致了我无法正常运行该应用程序。于是&#xff0c;我开始了一场寻找和修复旅程。然而…

RFID技术助力汽车零配件装配产线,提升效率与准确性

随着科技的不断发展&#xff0c;越来越多的自动化设备被应用到汽车零配件装配产线中。其中&#xff0c;射频识别&#xff08;Radio Frequency Identification&#xff0c;简称RFID&#xff09;技术凭借其独特的优势&#xff0c;已经成为了这一领域的重要技术之一。本文将介绍RF…

【BUG】docker安装nacos,浏览器却无法访问到页面

个人主页&#xff1a;金鳞踏雨 个人简介&#xff1a;大家好&#xff0c;我是金鳞&#xff0c;一个初出茅庐的Java小白 目前状况&#xff1a;22届普通本科毕业生&#xff0c;几经波折了&#xff0c;现在任职于一家国内大型知名日化公司&#xff0c;从事Java开发工作 我的博客&am…

go 协程并发数控制

错误的写法&#xff1a; 这里的<-ch 是为了从channel 中读取 数据&#xff0c;为了不使channel通道被写满&#xff0c;阻塞 go 协程数的创建。但是请注意&#xff0c;go workForDraw(v, &wg) 是不阻塞后续的<-ch 执行的&#xff0c;所以就一直go workForDraw(v, &…

数学建模之“灰色预测”模型

灰色系统分析法在建模中的应用 1、CUMCM2003A SARS的传播问题 2、CUMCM2005A长江水质的评价和预测CUMCM2006A出版社的资源配置 3、CUMCM2006B艾滋病疗法的评价及疗效的预测问题 4、CUMCM2007A 中国人口增长预测 灰色系统的应用范畴大致分为以下几方面: (1&#xff09;灰色关…

js简介以及在html中的2种使用方式(hello world)

简介 javascript &#xff1a;是一个跨平台的脚本语言&#xff1b;是一种轻量级的编程语言。 JavaScript 是 Web 的编程语言。所有现代的 HTML 页面都使用 JavaScript。 HTML&#xff1a; 结构 css&#xff1a; 表现 JS&#xff1a; 行为 HTMLCSS 只能称之为静态网页&#xff0…

IronPDF for .NET Crack

IronPDF for .NET Crack ronPDF现在将等待HTML元素加载后再进行渲染。 IronPDF现在将等待字体加载后再进行渲染。 添加了在绘制文本时指定旋转的功能。 添加了在保存为PDFA时指定自定义颜色配置文件的功能。 IronPDF for.NET允许开发人员在C#、F#和VB.NET for.NET Core和.NET F…

批量提取文件名到excel,详细的提取步骤

如何批量提取文件名到excel&#xff1f;我们的电脑中可能存储着数量非常多的电子文件&#xff0c;现在需要快速将这些文件的名称全部提取到Excel中。虽然少量数据可以通过复制粘贴的方式轻松完成&#xff0c;但是对于上万个数据而言&#xff0c;复制粘贴都是行不通的&#xff0…

改进YOLO系列:2.添加ShuffleAttention注意力机制

添加ShuffleAttention注意力机制 1. ShuffleAttention注意力机制论文2. ShuffleAttention注意力机制原理3. ShuffleAttention注意力机制的配置3.1common.py配置3.2yolo.py配置3.3yaml文件配置1. ShuffleAttention注意力机制论文 论文题目:SA-NET: SHUFFLE ATTENTION …

【CSS动画02--卡片旋转3D】

CSS动画02--卡片旋转3D 介绍代码HTMLCSS css动画02--旋转卡片3D 介绍 当鼠标移动到中间的卡片上会有随着中间的Y轴进行360的旋转&#xff0c;以下是几张图片的介绍&#xff0c;上面是鄙人自己录得一个供大家参考的小视频&#x1f92d; 代码 HTML <!DOCTYPE html>…

计算机视觉--距离变换算法的实战应用

前言&#xff1a; Hello大家好&#xff0c;我是Dream。 计算机视觉CV是人工智能一个非常重要的领域。 在本次的距离变换任务中&#xff0c;我们将使用D4距离度量方法来对图像进行处理。通过这次实验&#xff0c;我们可以更好地理解距离度量在计算机视觉中的应用。希望大家对计算…

MobaXterm网络远程工具介绍下载安装破解使用

一、介绍 obaXterm 是远程计算机的工具箱。在单个 Windows 应用程序中&#xff0c;它提供了大量为程序员、网站管理员、IT 管理员量身定制的功能。 MobaXterm 为 Windows 桌面提供了重要的远程网络工具&#xff08;SSH、X11、RDP、VNC、FTP、MOSH 等&#xff09;和Unix 命令&a…

Unity 找不到 Navigation 组件的解决

当我们想利用unity 里面的Navigation 组件来实现我们的物体的自动导航时&#xff0c;有时竟然会发现我们的菜单栏里面找不到 该组件 这时我们应该怎么办&#xff1f; 请确保你的项目中已经导入了Unity的AI模块。要导入该模块&#xff0c;请打开"Project Settings"&am…

计算机网络----CRC冗余码的运算

目录 1. 冗余码的介绍及原理2. CRC检验编码的例子3. 小练习 1. 冗余码的介绍及原理 冗余码是用于在数据链路层的通信链路和传输数据过程中可能会出错的一种检错编码方法&#xff08;检错码&#xff09;。原理&#xff1a;发送发把数据划分为组&#xff0c;设每组K个比特&#…

pytest自动化测试框架,真正做到从0到1由浅入深详细讲解【万字级】

目录 嗨咯铁汁们&#xff0c;很久不见&#xff0c;我还是你们的老朋友凡叔&#xff0c;这里也感谢各位小伙伴的点赞和关注&#xff0c;你们的三连是我最大的动力哈&#xff0c;我也不会辜负各位的期盼&#xff0c;这里呢给大家出了一个pytest自动化测试框架由浅入深详细讲解。 …

Tomcat日志中文乱码

修改安装目录下的日志配置 D:\ProgramFiles\apache-tomcat-9.0.78\conf\logging.properties java.util.logging.ConsoleHandler.encoding GBK

thinkphp6前后端验证码分离以及验证

1.验证码接口生成验证码: public function verify(){return captcha(); } 也可以自己写方法 2.验证方法和普通模式session验证有区别,需要改原文件: 修改后的代码: <?php // +---------------------------------------------------------------------- // | ThinkP…

[oneAPI] 使用字符级 RNN 生成名称

[oneAPI] 使用字符级 RNN 生成名称 oneAPI特殊写法使用字符级 RNN 生成名称Intel Optimization for PyTorch数据下载加载数据并对数据进行处理创建网络训练过程准备训练训练网络 结果 参考资料 比赛&#xff1a;https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0517…

万字长文·通俗易懂·一篇包掌握——输入/输出·文件操作(c语言超详细系列)(二)

前言&#xff1a;Hello&#xff0c;大家好&#x1f618;&#xff0c;我是心跳sy&#xff0c;上一节我们主要学习了格式化输入输出的基本内容&#xff0c;这一节我们对格式化进行更加深入的了解&#xff0c;对文件概念进行介绍&#xff0c;并且对输入、输出与文件读写的基本概念…