53 两数组的交集(Intersection of Two Arrays)
文章目录
- 1 题目
- 2 解决方案
- 2.1 思路
- 2.3 时间复杂度
- 2.4 空间复杂度
- 3 源码
- 3.1 排序+合并的方式
- 3.2 二分搜索的方式
- 3.3 哈希表的方式
1 题目
题目:两数组的交集(Intersection of Two Arrays)
描述:给出两个数组,写出一个方法求出它们的交集。
- 结果中的每个元素必须是唯一的。
lintcode题号——547,难度——easy
样例1:
输入: nums1 = [1, 2, 2, 1], nums2 = [2, 2],
输出: [2].
样例2:
输入: nums1 = [1, 2], nums2 = [2],
输出: [2].
2 解决方案
2.1 思路
本题可以使用多种方式来解,排序+合并、排序+二分、哈希表。
使用先排序再合并的方式,在逐一合并的过程中找到交集,从两个数组头部开始,对比大小,将找到的相同值放入结果中,注意去除重复元素,以此类推直到其中一个数组为空即可。
使用二分搜索的方式,将其中一个数组排序,然后遍历另一个数组中的所有元素在已排序的数组中进行二分搜索,找到的元素放入结果中,同样需要去除重复元素。
使用哈希表的方式,将其中一个数组放入哈希表中,然后遍历另一个数组中的所有元素在哈希表中进行查找,找到的元素放入结果中,同样也要去除重复。
2.3 时间复杂度
假设数组一的长度m,数组二的长度n,m要大于n。
先排序再合并的方式,两个数组都排序耗时O(n*log n)
、O(m*log m)
,合并操作的耗时O(m + n)
,总时间复杂度为O(nlogn + mlogm + m + n) = O(n*log n + m*log m)
。
使用二分搜索的方式,对其中一个数组排序耗时O(m*log m)
,遍历另一个数组的耗时O(n)
,在已排序数组中进行二分搜索的耗时O(log m)
,总时间复杂度为O(m*log m + n*log m) = O((m+n)*log m)
,可以看出该方式中将较小的数组进行排序可以减少计算耗时。
使用哈希表的方式,将其中一个数组放入哈希表耗时O(m)
,遍历另一个数组的耗时O(n)
,在哈希表中查找一个元素的耗时为O(1)
,总时间复杂度为O(m + n)
。
2.4 空间复杂度
三种方式的空间复杂度也不一样。
先排序再合并的方式,不使用额外空间,空间复杂度为O(1)
。
使用二分搜索的方式,不使用额外空间,空间复杂度为O(1)
。
使用哈希表的方式,把较小的数组放入哈希表,使用的额外空间较小,空间复杂度为O(min{m,n})
。
3 源码
3.1 排序+合并的方式
细节:
- 排序+合并,时间复杂度O(nlog n + mlog m),空间复杂度O(1)。
C++版本:
/**
* @param nums1: an integer array
* @param nums2: an integer array
* @return: an integer array
* we will sort your return value in output
*/
vector<int> intersection(vector<int> &nums1, vector<int> &nums2) {// write your code herevector<int> result;if (nums1.empty() || nums2.empty()){return result;}// 分别对两个数组排序sort(nums1.begin(), nums1.end());sort(nums2.begin(), nums2.end());// 合并int i = 0;int j = 0;while (i < nums1.size() && j < nums2.size()){if (nums1.at(i) < nums2.at(j)){i++;}else if (nums1.at(i) > nums2.at(j)){j++;}else{if (result.empty() || nums1.at(i) != result.back()) // 跳过重复的元素,先判断结果容器是否空,再取back(),否则越界{result.push_back(nums1.at(i));}i++;j++;}}return result;
}
3.2 二分搜索的方式
细节:
- 二分搜索,时间复杂度O((m+n)*log m),空间复杂度O(1)。
- 两个数组都可能包含重复元素,结果中使用set进行去重。
C++版本:
/**
* @param nums1: an integer array
* @param nums2: an integer array
* @return: an integer array
* we will sort your return value in output
*/
vector<int> intersection(vector<int> &nums1, vector<int> &nums2) {// write your code herevector<int> result;if (nums1.empty() || nums2.empty()){return result;}// 比较两个数组长度vector<int> * small = nullptr;vector<int> * big = nullptr;if (nums1.size() < nums2.size()){small = &nums1;big = &nums2;}else{small = &nums2;big = &nums1;}// 对较短的数组排序sort(small->begin(), small->end());// 遍历较长的数组元素,逐个进行二分搜索unordered_set<int> resultSet;for (auto it : *big){// 二分搜索if (binarySearch(*small, it)){resultSet.insert(it); // 去重}}// 构造结果for (auto it : resultSet){result.push_back(it);}return result;
}bool binarySearch(vector<int> & nums, int target)
{int start = 0;int end = nums.size() - 1;while (start + 1 < end){int mid = start + (end - start) / 2;if (nums.at(mid) < target){start = mid;}else if (nums.at(mid) > target){end = mid;}else{return true;}}if (nums.at(start) == target){return true;}if (nums.at(end) == target){return true;}return false;
}
3.3 哈希表的方式
细节:
- 哈希表,时间复杂度O(m + n),空间复杂度O(min{m,n})。
- 两个数组都可能包含重复元素,结果中使用set进行去重。
C++版本:
/**
* @param nums1: an integer array
* @param nums2: an integer array
* @return: an integer array
* we will sort your return value in output
*/
vector<int> intersection(vector<int> &nums1, vector<int> &nums2) {// write your code herevector<int> result;if (nums1.empty() || nums2.empty()){return result;}// 比较两个集合大小vector<int> * small;vector<int> * big;if (nums1.size() < nums2.size()){small = &nums1;big = &nums2;}else{small = &nums2;big = &nums1;}// 较小的放入hash表中set<int> hash;for (auto it : *small){hash.insert(it);}// 遍历较大的集合set<int> resultSet; // 产生的结果也需要去重,因为num2中可能有重复,不要求有序的话,可以使用unordered_setfor (auto it : *big){if (hash.find(it) != hash.end()){resultSet.insert(it);}}// 构造结果for (auto it : resultSet){result.push_back(it);}return result;
}
53 两数组的交集(Intersection of Two Arrays)相关推荐
- 两数组的交集(无重复)Intersection of Two Arrays
2019独角兽企业重金招聘Python工程师标准>>> 问题: Given two arrays, write a function to compute their interse ...
- 如何用C#求两数组的交集和并集
string[] a1={"1","2"}; string[] a2={"2","3"}; Ilist<strin ...
- LintCode 两个数组的交集
547.两数组的交集 描述 给出两个数组,写出一个方法求出它们的交集 样例 例1: 输入: nums1 = [1, 2, 2, 1], nums2 = [2, 2], 输出: [2]. 例2: 输入: ...
- Leetcode-数据结构-350. 两个数组的交集 II
问题 给两个整数数组 nums1 和 nums2 ,请以 数组形式 返回两数组的 交集 (其在交集中出现的次数:等于该数字在两个数组中出现次数的最小值). 返回结果中 每个元素出现的次数(for遍历) ...
- LeetCode简单题之两个数组的交集 II
题目 给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集.返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值).可以不考 ...
- 12. Leetcode 350. 两个数组的交集 II (数组-分离双指针)
给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集.返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值).可以不考虑输出 ...
- leetcode系列-350.两个数组的交集II
leetcode系列–第350题.两个数组的交集II 给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集. 返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一 ...
- LeetCode 350. 两个数组的交集 II
350. 两个数组的交集 II 难度简单640收藏分享切换为英文接收动态反馈 给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集.返回结果中每个元素出现的次数,应与元素在两 ...
- Python计算两个numpy数组的交集(Intersection)实战:两个输入数组的交集并排序、获取交集元素及其索引、如果输入数组不是一维的,它们将被展平(flatten),然后计算交集
Python计算两个numpy数组的交集(Intersection)实战:两个输入数组的交集并排序.获取交集元素及其索引.如果输入数组不是一维的,它们将被展平(flatten),然后计算交集 目录
最新文章
- 4514: [Sdoi2016]数字配对
- eBCC性能分析最佳实践(1) - 线上lstat, vfs_fstatat 开销高情景分析...
- JAVA并发之多线程基础(2)
- 点云网络的论文理解(一)-点云网络的提出 PointNet : Deep Learning on Point Sets for 3D Classification and Segmentation
- C语言二级指针与典型应用(1)
- Android --- allowBackup 属性的含义和危险性实例讲解
- phpAmin如何导入导出大数据文件?
- OpenGL Sharders(着色器) 入门
- mysql truncate partition_实战mysql分区(PARTITION)
- Oracle11gR2 RAC+DataGuard安装实施维护2+1_数据库集群容灾视频教程
- 670. Maximum Swap 允许交换一个数 求最大值
- 光盘勘误——《Visual C# 2005 程序开发与界面设计秘诀》
- 云计算之IasS、PasS、SaaS
- Bootstrap 按钮(实例 )
- Tomcat内存溢出及配置解决方案
- 分享一个修改电脑IP的小工具
- Kaggle账号的注册
- access中本年度的四月一日_2014年3月计算机二级ACCESS上机试题及详解十二
- 查询手机号的归属地及运营商接口
- mumu模拟器显示服务器出错,用mumu模拟器显示错误代码