349. 两个数组的交集 题解

news2024/11/17 1:50:03

题目描述: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 较小时,两种方法的时间复杂度都差不多,但哈希集合方法在一些特定情况下可能会稍微快一些。然而,如果在意空间复杂度,排序和双指针方法的空间复杂度更低。


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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《零基础7天入门Arduino物联网-04》电路基础知识上

配套视频课程&#xff1a;《零基础学Arduino物联网&#xff0c;入门到进阶》 配套课件资料获取&#xff1a;微联实验室 配套学习套件购买&#xff1a;淘宝搜索店铺【微联实验室】 直流电与交流电 直流电&#xff08;DC&#xff09; 是指电流的方向始终保持不变的电流。这意味着…

Hyperledger Fabric的使用及开发

Hyperledger Fabric是Linux基金会发起的一种跨行业的区块链技术&#xff0c;目前在多家大型公司有着应用&#xff0c;这里就不多做HF本身的介绍了&#xff0c;有兴趣可关注其官网。 1. 准备工作&#xff1a; 开始前需要一定的准备工作&#xff0c;安装各类中间件&#xff1a;…

JVM——HotSpot的算法细节实现

一、根节点枚举 固定可作为GC Roots的节点主要在全局性的引用&#xff08;如常量或类静态属性&#xff09;与执行上下文&#xff08;如栈帧中的本地变量表&#xff09;中&#xff0c;尽管目标明确&#xff0c;但查找要做到高效很难。现在java应用越来越庞大&#xff0c;光方法区…

啥是虚拟机

虚拟机这个概念第一次听到还是在我大二学计算机网络做实验的时候听说过&#xff0c;第二次算比较熟练地使用应该是在大三下学期的大数据课程&#xff0c;做实验的时候也算是学到了许多Linux的命令。但到底什么是虚拟机&#xff0c;我还是搞不清楚的&#xff0c;所以&#xff0c…

【八股】2023秋招八股复习笔记1(CSBase+部分WXG题)

文章目录 MYSQL & redis网络 & 系统安全 & C招聘要求&#xff08;x3&#xff09;部分面经和题目&#xff08;WXG-后端&#xff09;&#xff08;x5&#xff09; MYSQL & redis redis&#xff1a;memcached/mysql&#xff0c;线程模型&#xff08;6.0多线程&…

css实现div内文字自动滚动

网上找了好久&#xff0c;终于找到了个能实现的&#xff0c;把它整理一下。 需求&#xff1a;表格内字体过长实现自动滚动 实现思路如下&#xff1a; html&#xff1a; <div class"item-column" style"background: rgb(12, 87, 154); width: 18%; height: 6…

Msvcr120.dll文件缺失怎么办.msvcr120.dll错误的解决方法

在使用某些软件时你是否有遇到过Msvcr120.dll文件缺失&#xff0c;msvcr120.dll是 Microsoft Visual C Redistributable 中的一个重要文件&#xff0c;所以它的缺失会导致应用程序无法正常使用或崩溃。那么出现这种情况应该怎么办呢&#xff1f;以下教大家几种解决方法。 一.导…

线性代数(四) 特征值相似矩阵

前言 前面主要讲述的是方程组和矩阵的关系&#xff0c;现在了解下矩阵和矩阵的关系 方阵的特征值与特征向量 假设A为n阶方阵&#xff0c;对于一个数 λ \lambda λ 若存在&#xff1a;非零列向量 α \alpha α&#xff0c;使得&#xff1a; A α ⃗ λ α ⃗ A\vec{\alp…

轮腿机器人的PID控制

1 PID介绍 PID&#xff08;Proportional Integral Derivative&#xff09;控制系统。其实质是根据输入的偏差值&#xff0c;按比例、积分、微分的函数关系进行运算&#xff0c;运算结果用以输出进行控制。它是在长期的工程实践中总结出来的一套控制方法&#xff0c;实际运行经…

在CentOS 7上使用kubeadm部署Kubernetes集群

如有错误&#xff0c;敬请谅解&#xff01; 此文章仅为本人学习笔记&#xff0c;仅供参考&#xff0c;如有冒犯&#xff0c;请联系作者删除&#xff01;&#xff01; 前言&#xff1a; Kubernetes是一个开源的容器编排平台&#xff0c;用于管理和自动化部署容器化的应用程序。…

C#8.0本质论第三章--更多数据类型

C#8.0本质论第三章–更多数据类型 3.1类型的划分 一个类型要么是值类型&#xff0c;要么是引用类型。区别在于拷贝方式&#xff1a;值类型数据总是拷贝值&#xff1b;引用类型的数据总是拷贝引用。 3.1.1值类型 3.1.2引用类型 引用类型的变量存储对数据存储位置的引用。 3.…

Datawhale Django入门组队学习Task02

Task02 首先启动虚拟环境&#xff08;复习一下之前的&#xff09; 先退出conda的&#xff0c; conda deactivate然后cd到我的venv下面 &#xff0c;然后cd 到 scripts&#xff0c;再 activate &#xff08;powershell里面&#xff09; 创建admin管理员 首先cd到项目路径下&a…

笨办法学python3进阶篇pdf,笨方法学 python3怎么样

本篇文章给大家谈谈《“笨办法”学python(第3版)》&#xff0c;以及笨办法学python3进阶篇pdf下载&#xff0c;希望对各位有所帮助&#xff0c;不要忘了收藏本站喔。 接着前天的总结 习题21&#xff1a;函数可以返回某些东西 定义函数的加减乘除&#xff0c;以及嵌套使用 习题2…

PHP实现轻量级WEB服务器接收HTTP提交的RFID刷卡信息并回应驱动读卡器显示播报语音

本示例使用的读卡器&#xff1a;RFID网络WIFI无线TCP/UDP/HTTP可编程二次开发读卡器POE供电语音-淘宝网 (taobao.com) <?php mb_http_output(utf-8); $port88; $socket socket_create(AF_INET, SOCK_STREAM, SOL_TCP); $bool socket_bind($socket, "0.0.0.0",…

深度学习入门-3-计算机视觉-卷积神经网络

一、计算机视觉 1.概述 计算机视觉作为一门让机器学会如何去“看”的学科&#xff0c;具体的说&#xff0c;就是让机器去识别摄像机拍摄的图片或视频中的物体&#xff0c;检测出物体所在的位置&#xff0c;并对目标物体进行跟踪&#xff0c;从而理解并描述出图片或视频里的场…

Python进阶系列(二)— 类与对象

对象 Python是一个面向对象的语言Python的内置类型实例都是对象对象包含数据和方法集合 类 类是对现实中的事物进行抽象的数据表示&#xff0c;用来定义对象们的数据结构&#xff0c;对象由实例化类获得。 例如这是一个玩家类&#xff0c;玩家有x&#xff0c;y和生命值三个…

程序的机器级表示

程序的机器级表示 程序编码数据格式访问信息的方式 所有的高级语言&#xff0c;都会被计算机翻译为机器代码&#xff0c;然后再根据汇编代码生成可执行的机器代码。二进制的机器代码我们人类肯定是读不懂了&#xff0c;但是汇编代码还是可以简单了解一下的。CPU 的 PC、寄存器、…

ATTCK覆盖度97.1%!360终端安全管理系统获赛可达认证

近日&#xff0c;国际知名第三方网络安全检测服务机构——赛可达实验室&#xff08;SKD Labs&#xff09;发布最新测试报告&#xff0c;360终端安全管理系统以ATT&CK V12框架攻击技术覆盖面377个、覆盖度97.1%&#xff0c;勒索病毒、挖矿病毒检出率100%&#xff0c;误报率0…

详解web前端长度单位(px、em、rem、%、vw/vh、vmin/vmax、vm、calc())

1&#xff09;简介 在前端开发中&#xff0c;会遇到各种不同类型的长度单位&#xff0c;比如px,em,rem等。 而整体的长度单位分为两大类&#xff1a; 绝对长度单位包括&#xff1a;in,cm, mm, q, pt, pc, px 相对长度单位包括&#xff1a;em, rem, %, vw, vh, vmax, vmin, vm,…

python基础语法 百度网盘,python基础语法个人笔记

大家好&#xff0c;本文将围绕python基础语法 百度网盘展开说明&#xff0c;python基础语法个人笔记是一个很多人都想弄明白的事情&#xff0c;想搞清楚python基础语法合集下载需要先了解以下几个事情。 前言 Python是一种多功能语言。它经常用作Web应用程序的脚本语言&#xf…