Python 解LeetCode:Intersection of Two Arrays

        最近,在用解决LeetCode问题的时候,做了349: Intersection of Two Arrays这个问题,就是求两个列表的交集。我这种弱鸡,第一种想法是把问题解决,而不是分析复杂度,于是写出了如下代码:

 1 class Solution(object):
 2     def intersection(self, nums1, nums2):
 3         """
 4         :type nums1: List[int]
 5         :type nums2: List[int]
 6         :rtype: List[int]
 7         """
 8         ret = []
 9         for i in nums1:
10             if i in nums2 and not i in ret:
11                 ret.append(i)
12         return ret

      打眼一看,嗯,挺好,时间负责度是O(n),点击提交,AC;打开结果一看,EXM?才击败了15%?这是O(n*2)的复杂度啊!哪里有问题呢?再一看,问题就出在i in nums2这个语句中了,在Python中,List的in操作的时间复杂度是O(n),也就是实现的算法复杂度果然是O(n2)了。看来只是单纯的看表面的循环的复杂度是不行的,还是要了解一些内部的实现。等等,这是两个列表的交集操作啊,集合才是完美的实现,python自带了集合类型set。嗯,就用集合了,又写了如下代码:

1 class Solution(object):
2     def intersection(self, nums1, nums2):
3         """
4         :type nums1: List[int]
5         :type nums2: List[int]
6         :rtype: List[int]
7         """
8         return list(set(nums1).intersection(set(nums2)))

      提交,AC,查看结果,beat 80%,果然快了好多,代码还更加Pythonic了。对于Python的各种数据类型的时间复杂度,可以看这里。写代码的过程中,要充分了解Python的内部实现,才能运行的更快啊!

    然后又看到了350. Intersection of Two Arrays II,这次的结果是两个数组的交集,但是可以有重复元素了,要运行O(n)的话,这次直接想到了用空间换时间,无非是使用hash了,Python的字典就是hash实现的,于是写了:

 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         tmp_dict = dict()
 9         ret = []
10         for i in nums1:
11             tmp_dict[i] = tmp_dict[i] + 1 if tmp_dict.get(i) else 1
12         for n in nums2:
13             if tmp_dict.get(n) > 0:
14                 ret.append(n)
15                 tmp_dict[n] -= 1
16         return ret

    提交运行,果然,击败了90%。结果不错,但是我还是想到用Python的Countrs了,这样会不会更快呢?点击打开讨论区,果然看到有这样用的:

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         a, b = map(collections.Counter, (nums1, nums2))
9         return list((a & b).elements())

    代码更短了,对于熟悉Counters的人来说,也更好理解了,不过运行效率也没有提升。至于哪种方式好,就是另外一个问题了。

原文地址:https://www.cnblogs.com/qiaojushuang/p/7698870.html