【初级算法】两个数组的交集 II 2120.8.9
【两个数组的交集 II】 题目:
给定两个数组,编写一个函数来计算它们的交集。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]
说明:
输出结果中每个元素出现的次数,应与元素在两个数组中出现次数的最小值一致。
我们可以不考虑输出结果的顺序。
进阶:
如果给定的数组已经排好序呢?你将如何优化你的算法?
如果 nums1 的大小比 nums2 小很多,哪种方法更优?
如果 nums2 的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/x2y0c2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
1.0 自己尝试解答
1 class Solution(object): 2 def intersect(self, nums1, nums2): 3 """ 4 :type nums1: List[int] 5 :type nums2: List[int] 6 :rtype: List[int] 7 """ 8 mixed = [] 9 p = len(nums1) 10 q = len(nums2) 11 for i in range(p): # range执行到p的前一位 12 for j in range(q): 13 if nums1[i] == nums2[j]: 14 if nums1[i] not in mixed: 15 x = 0 16 y = 0 17 nums = nums1[i] 18 for k in nums2: 19 if k == nums: 20 x += 1 21 for h in nums1: 22 if h == nums: 23 y += 1 24 minnum = min(x, y) 25 for m in range(minnum): 26 mixed.append(nums) 27 else: 28 continue 29 else: 30 continue 31 return mixed

思路:自己分析了一下交集,首先要判断是否有交集,然后再判断两个数组中出现的最小次数。
判断是否有交集很好判断,分别把两个数组的数取出来,然后一循环对比,就能找到交集。
问题是如何判断两个数组中出现的最小次数,并且还要放到mixed(返回值)中,不能多放,不能少放。最开始没有思路想看看是否有函数能简化过程,没找到。然后又搜索了数组中重复的数字,很遗憾发现这道算法题中的数字是有范围的,和我要的条件不符,不过也因此对哈希表有所了解了。最后,只能想到笨方法,分别在nums2、nums1取值对比,若相等x、y分别加一,最后用python自带的min函数取出x,y中的最小值,再使用append函数加在mixed上。其中调试了多遍,也对一些知识有了更深的认识,巩固了不熟练的地方。最让我开心的是居然通过了!撒花庆祝*★,°*:.☆( ̄▽ ̄)/$:*.°★* ,开森
还有其他的方法,还有待学习,gogogo!
2.0 其他思路
2.1 (8.10)
如果不要求返回元素的个数,可以直接使用python的
1 list(set(nums1)&set(nums2))
set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等。
list() 方法用于将元组转换为列表。
【问题:为什么要用list?】
然后自己去跑了一下

发现输出的是set类型,也就是list()函数的作用是把set类型变成了list类型
那么,又有新的问题了,set()类型是什么呢?
在一篇文章中我找到了答案:
Python基本数据类型之set
一、定义
set是一个无序且不重复的元素集合。
集合对象是一组无序排列的可哈希的值,集合成员可以做字典中的键。集合支持用in和not in操作符检查成员,由len()内建函数得到集合的基数(大小), 用 for 循环迭代集合的成员。但是因为集合本身是无序的,不可以为集合创建索引或执行切片(slice)操作,也没有键(keys)可用来获取集合中元素的值。
set和dict一样,只是没有value,相当于dict的key集合,由于dict的key是不重复的,且key是不可变对象因此set也有如下特性:
-
不重复
-
元素为不可变对象
创建:

(来源:https://www.cnblogs.com/whatisfantasy/p/5956775.html)
这篇文章后面还附有set的基本操作,就不在这里贴了,感兴趣的可以阅读原文。
2.2 排序求交集
自己写的看懂了思路就能顺理成章的写下来这个算法
1 class Solution(object): 2 def intersect(self, nums1, nums2): 3 """ 4 :type nums1: List[int] 5 :type nums2: List[int] 6 :rtype: List[int] 7 """ 8 nums1.sort() 9 nums2.sort() 10 mixed = [] 11 i = 0 12 j = 0 13 while i<len(nums1) and j<len(nums2): 14 if nums1[i] == nums2[j]: 15 mixed.append(nums1[i]) 16 if nums1[i] == nums2[j]: 17 i += 1 18 j += 1 19 elif nums1[i] > nums2[j]: 20 j += 1 21 elif nums1[i] < nums2[j]: 22 i += 1 23 return mixed 24 25 if __name__ == '__main__': 26 num1 = [4,9,4,5] 27 num2 = [9,4,8,4] 28 #num1 = [1,2,2,1] 29 #num2 = [2,2] 30 result = Solution().intersect(num1, num2) 31 print(result) 32
思路:
①先对两个列表进行排序
②分别从第0位开始比较
③判断。如果两个数相等就把这个数放到空列表mix中;然后执行下面的操作
④第二次判断。相等则同时往后移动;不相等则看哪一边的数更小,更小的一方往后移动。

这个明显时间上快了很多,我的笨方法还真是慢啊...苦笑
2.3 两列表长度相差大求交集
自己写的代码:
1 class Solution(object): 2 def intersect(self, nums1, nums2): 3 """ 4 :type nums1: List[int] 5 :type nums2: List[int] 6 :rtype: List[int] 7 """ 8 mixed = [] 9 if len(nums1) > len(nums2): 10 nums1, nums2 = nums2, nums1 11 12 len1 = len(nums1) 13 j = 0 14 i = 0 15 while j<len(nums2) and i<len1: 16 if nums1[i] == nums2[j]: 17 mixed.append(nums1[i]) 18 nums2.pop(j) 19 i += 1 20 j = 0 21 elif nums1[i] != nums2[j]: 22 j += 1 23 if j == len(nums2) and i < len1: 24 j = 0 25 i += 1 26 return mixed 27

好慢啊,哪里是不是写的不对啊
参考答案:
1 class Solution(object): 2 def intersect(self, nums1, nums2): 3 """ 4 :type nums1: List[int] 5 :type nums2: List[int] 6 :rtype: List[int] 7 """ 8 mixed = [] 9 if len(nums1) > len(nums2): 10 nums1, nums2 = nums2, nums1 11 for n in nums1: 12 if n in nums2: 13 mixed.append(n) 14 nums2.remove(n) 15 return mixed
比起我的代码太简洁了吧,悲桑逆流成河。
原来直接用in就可以啊,我都没有想到。基础不是很扎实啊。不过,多见几次就会会了。
remove() 函数用于移除列表中某个值的第一个匹配项。无返回值。

参数
- obj -- 列表中要移除的对象。
pop() 函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值。

参数
- obj -- 可选参数,要移除列表元素的索引值,不能超过列表总长度,默认为 index=-1,删除最后一个列表值。
| remove()函数 | pop()函数 | ||
| 相同点 | ① | 都是移除函数 | |
| ② | 都作用于列表 | ||
| 不同点 | ①有无返回值 | 无 | 有,可将弹出值赋值给变量 |
| ②括号() | 括号中必须填写内容,且内容为元素的值 | 括号中不必一定填写内容,内容为列表索引值 | |
| ③移除位置 | 从正向开始,移除第一个 | 默认为[index=-1],可以任意指定元素位置 | |
2.4 方法
1 class Solution(object): 2 def intersect(self, nums1, nums2): 3 """ 4 :type nums1: List[int] 5 :type nums2: List[int] 6 :rtype: List[int] 7 """ 8 inter = set(nums1) & set(nums2) 9 l = [] 10 for i in inter: 11 l += [i] * min(nums1.count(i), nums2.count(i)) 12 return l

※ value为任何类型,列表也可。

列表+列表

2.5 哈希表
待补充待补充

浙公网安备 33010602011771号