【初级算法】两个数组的交集 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也有如下特性:

  1. 不重复

  2. 元素为不可变对象

创建:

 

(来源: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 哈希表

待补充待补充

posted @ 2021-08-09 09:17  阿吽  阅读(203)  评论(0)    收藏  举报