一段时间没有练习代码,真就生疏了。果然代码是要天天练的。
今天的题目需要使用字典,不过年代久远,基本的操作又都忘了……
业精于勤荒于嬉,果然不是随便说说的。
题目
350. 两个数组的交集II
难度:简单
题目分析:这道题的难度简单,可能在于可以直接调用python的库来进行解答,不过,如果自己实现,对于字典的操作的理解,要求还是挺高的,当然,对于生疏的我来说。
解法一:最粗糙的版本
class Solution:
def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
# 使用哈希表,先把短的记录,然后比较新的
n1 = len(nums1)
n2 = len(nums2)
if n1 == 0 or n2 == 0:
return []
if n1 < n2:
short = list(nums1)
long_n = list(nums2)
else:
short = list(nums2)
long_n = list(nums1)
short_dict = {}
for num in short:
short_dict[num] = short_dict.get(num, 0) + 1
res = []
# 开始比较
for num in long_n:
if num in short_dict.keys() and short_dict[num] >0:
res.append(num)
short_dict[num] -= 1
return res
运行结果:
分析:
- 一开始设想拿短的数组来分析,于是进行交换,不过代码太复杂(后来看了别人的代码,又回忆起来了)
- 参考了其他代码,空列表的情况可以整合到主代表一起,看起来代码会简洁,对于速度的影响,应该可以忽略。
解法二:使用内置的库
class Solution:
def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
from collections import Counter
res = []
for k, v in (Counter(nums1) & Counter(nums2)).items():
for _ in range(v):
res.append(k) # v 的个数就是k应该重复的个数
return res
运行结果:
分析:
- 运行速度跟我们不调用包的差别不大;
- 代码
for k, v in (Counter(nums1) & Counter(nums2)).items():
先把两个数组里面的数字进行统计,然后求了个并集;最后形成的是一个字典
3. 下一句代码就是把value值拿出来,确定下要重复多少次key。
解法三:重新整理答案
class Solution:
def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
# 简洁版
if len(nums1) > len(nums2):
# 默认 nums1 是数量小的那一方
nums1, nums2 = nums2, nums1
res = []
hash_map = {}
for num in nums1:
hash_map[num] = hash_map.get(num, 0) + 1
for num in nums2:
if num in hash_map and hash_map[num] > 0:
res.append(num)
hash_map[num] -= 1
return res
运行结果:
总结:
- 如果数据非常多,没法一次性导入内存,用字典的方法是最好的;
- 另外一种解法是把数据进行排序,这种也可以快速进行比较;不过,只适合数据量不多的情况。