349. 两个数组的交集——集合的交集、并集和差集+集合的遍历

该博客介绍了如何利用Java解决LeetCode中的349题,即找到两个数组的交集。通过示例展示了当不使用集合时的困难,以及使用集合(如Set)后问题变得简单。博主分享了两种解决方案,一种不使用集合,另一种利用集合的retainAll()方法。还补充了集合操作如差集、并集和遍历的相关代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目来源:https://leetcode-cn.com/problems/intersection-of-two-arrays/

给定两个数组,编写一个函数来计算它们的交集。

 

示例 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
示例 2:

输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
 

说明:

输出结果中的每个元素一定是唯一的。
我们可以不考虑输出结果的顺序。

#######################################################

这道题一开始我没有想到用集合,感觉非常的麻烦,假如不用集合,用数组保存结果,那数组长度用多长?怎么得到最终要返回的结果数组(要删除哪些数组元素),导致我没有写出来,看了答案用了集合就容易多了!比如,需要去重,就想到可以用set。

两种方法的代码如下,第二种使用了集合的retainAll方法。

第一种:

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        if(nums1.length==0||nums2.length=
交集的线性算法(原创) 对于给定的两个集合,使用哈希表可以在线性时间复杂度内得到他们的交集,具体说明如下: 假设有集合A={1, 7, 5, 13, 9, 10, 11}, B={5, 7, 10, 1, 18, 12}, 1)求交集,需要得到结果:A∩B={1, 5, 7,10} 思路如下: ①建立一个哈希表(HashTable),其键(KEY)表示集合中数字的值,其值(VALUE)表示集合中数字出现的次数 ②遍历集合A,将集合中的每个数字(KEY)插入哈希表,每个数字的出现次数(VALUE)设置为1 ③遍历集合B,对于集合中的每个数字: 如果哈希表中已经存在该数字,将对应的VALUE改为2 如果哈希表中不存在该数字,忽略 ④遍历哈希表,输出VALUE为2的数字,即得到AB的交集 2) 求,需要得到结果:AUB={1,5,7,9,10,11,12,13,18} 思路如下: ①建立一个哈希表(HashTable),其键(KEY)表示集合中数字的值,其值(VALUE)可以无视 ②遍历集合A,将集合中的每个数字(KEY)插入哈希表 ③遍历集合B,对于集合中的每个数字: 如果哈希表中已经存在该数字,忽略 如果哈希表中不存在该数字,将这个数字插入哈希表 ④遍历哈希表,输出哈希表中的每个KEY,即为AB的 上面以两个集合为例说明了交集的求法,事实上,上述算法可以很方便的扩展到3个或3个以上的集合 的求交集。另外求时,由于哈希表的值(VALUE)部分不需要用到,所以这个数据结构也可以更换为 哈希(HashSet)。 转载请注明出处。 VB中HashTable 2012-08-20 14:43:21| 分类: asp.net|举报|字号 订阅 首先定义一个hashtable Dim hstl As New Hashtable hstl.Add(key, value) 'java是用.put MS开始全面模仿java 这说说vb.net中的hashtable基本用法: 添加值:hstl.add(key,value) 通过key取值: hstl.Item(key).ToString 判断是否含有Key: ContainsKey(key) 判断是否含有value: ContainsValue(value) 遍历hashtable: Dim de As DictionaryEntry '泛型类 For Each de In hstl console.write(de.key & de.value) Next de hashtable不支持通过value取key. 求2个集合交集 第一种方法 最简单、粗暴的循环遍历2个集合,判断如果有相同的元素就取出来。假设集合1的长度为M,集合2的长度为N,那么,时间复杂度为:O(M*N) 代码: public static List GetIntersection(List list1, List list2) { List list3 = new List(); //第一种方法:循环遍历 //O(n×m) for (int i = 0; i < list1.Count; i++) { for (int j = 0; j < list2.Count; j++) { if (list1[i]==list2[j]) { list3.Add(list1[i]); } } } return list3; } 第二种方法 利用hash这种很有用的数据结构来实现。我们知道,hash的特点之一就是不允许有重复元素,即hash表中的元素都是唯一的。所以,我们的思路就是:先把第一个集合的所有元素都放进hashSet中,时间复杂度O(M);再把第二个集合中的元素放进hashSet中,如果有重复元素,就是这2个集合交集,时间复杂度为O(N)。即总的时间复杂度从O(M*N)降低到了O(M+N)。 代码: public static List GetIntersection2(List list1, List list2) { //第二种方法:hash List list3 = new List(); HashSet hashSet = new HashSet(); foreach (string item in list1) { hashSet.Add(item); } foreach (string item in list2) { if (hashSet.Add(item) == false) { list3.Add(item); } } return list3; } 测试 代码: static void Main(string[] args) { List list1 = new List(); list1.Add("apple"); list1.Add("banana"); list1.Add("pear"); list1.Add("orange"); list1.Add("grape"); List list2 = new List(); list2.Add("nokia"); list2.Add("sumsung"); list2.Add("htc"); list2.Add("apple"); list2.Add("orange"); List list =new List(); //test for two set join //list = TwoSetsIntersection.GetIntersection(list1, list2); list = TwoSetsIntersection.GetIntersection2(list1, list2); foreach (string item in list) { Console.Write(item + "\t"); } } 总结 hash的另一个特点是查找效率为O(1),惊人的高! 对于这道题目要是算出来O(M*N)的同学就应该补课了。出来混,迟早要还的。 HashSet类 HashSet类主要是设计用来做高性能运算的,例如对两个集合交集差集等。集合中包含一组不重复出现且无特性顺序的元素。 HashSet的一些特性如下: 1、HashSet中的值不能重复且没有顺序。 2、HashSet的容量会按需自动添加。 构造方法: HashSet() 默认相等比较器创建一个空的新实例。 HashSet(IEnumerable collection)  把指定集合中的collection中的数据复制到中 HashSet(IEqualityComparer comparer)  使用指定的相等比较器创建一个空的新实例 HashSet(IEnumerable collection,IEqualityComparer comparer)  使用指定的比较器实例化数据,且将指定集合中的元素复制到集合中。 因为HashSet是专门设计来做集合运算的,因此它提供的方法中有不少是集合运算相关的。 以下给出它的一些常用方法介绍 成员        类型        说明 Add        方法        将指定的元素添加到集合中 Clear        方法         清空集合中的所有元素 Contains     方法         确定某元素是否在HashSet中 Exists       方法         确定HashSet是否包含于指定条件相匹配的元素 ExceptWith    方法         从当前HashSet移除指定集合中的所有元素 IntersectWith   方法        修改当前的HashSet对象,以仅包含该对象指定集合中存在的元素 IsProperSubsetOf  方法        确定HashSet对象是否为指定集合的真子 IsProperSupersetOf 方法        确定HashSet对象是否为指定集合的真超 IsSunsetOf     方法         确定HashSet对象是否为指定集合的子 IsSupersetOf    方法         确定HashSet对象是否为指定集合的超 Remove      方法         从HashSet对象中移除指定的元素 RemoveWhere   方法         从HashSet集合中移除指定谓词所定义的条件相匹配的所有元素 SetEquals     方法         确定HashSet对象指定的集合中是否包含相同的元素 SynmmetricExceptWith  方法     修改当前的HashSet对象,以仅包含该对象或指定集合中存在的元素 TrimExcess    方法         将HashSet对象的容量设置为它所包含的元素的实际个数,向上舍入为接近的特性实现的值。 UnionWith     方法         修改当前的HashSet对象,以包含该对象本身指定集合中存在的所有元素 给个简单的例子,写不完的,总之记得HashSet主要的作用是用来进行,交集等运算的就OK了。 static void Main(string[] args) { HashSet hs = new HashSet(); hs.Add("你"); hs.Add("好"); hs.Add("吗"); HashSet hs1 = new HashSet(); hs1.Add("你"); hs1.Add("好"); bool b = hs1.IsProperSubsetOf(hs); //确定hs1是否是hs的真子 Console.WriteLine(b); //输出True HashSet hs2 = new HashSet(); hs2.Add("爱你"); IEnumerable list = hs.Union(hs2); //返回 foreach (string str in list) { Console.WriteLine(str); //输出 你 好 吗 爱你 } Console.ReadKey(); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值