解决之路= =
题目描述
测试案例(部分)
第一次
顺着“两个数组的交集”的思路想,先用集合处理nums1
和nums2
,然后通过“交集”运算得出列表res
,然后循环检查列表res
,得出各个元素在两个数组中出现的最小次数,最终在列表plus
中添上少的元素,借助python的列表相加,返回res+plus
就是答案。
class Solution(object):
def intersect(self, nums1, nums2):
res = list(set(nums1) & set(nums2))
plus = []
for i in res:
s = min(nums1.count(i), nums2.count(i))
for j in range(s - 1):
plus.append(i)
return res + plus
测试正确,提交通过。不过,效率不高。
第二次
想一想如何优化。在进阶提示中,第一条就是有序的两个数组会怎么优化算法。
看了看评论区,有人在两个有序数组的基础上再用双指针法进行遍历(假设是p1
和p2
两个指针,各自从nums1
和nums2
开始找),如果相同p1
和p2
一起+1
,不相同时,哪边小了哪边+1
,这样不但可以控制多次加入同样的元素,还保证了时间复杂度是O(m+n)。
按照这个思路我们来实现一下,转化成代码比较简单。
class Solution:
def intersect(self, nums1, nums2):
nums1.sort()
nums2.sort()
p1, p2 = 0, 0
res = []
while p1 < len(nums1) and p2 < len(nums2):
if nums1[p1] == nums2[p2]:
res.append(nums1[p1])
p1 += 1
p2 += 1
else:
if nums1[p1] < nums2[p2]:
p1 += 1
else:
p2 += 1
return res
测试正确,提交成功!
可以说,双指针法不一定局限于一个数据中使用。一个数组可以一前一后,然后夹住我们最终需要的结果;两个数组可以一个数组一个,从头到尾相互比对。
前面有题目也表示了双指针可以应用于有序数组也可以应用于无序,所以双指针法有灵活一点,针对需求,有时会有奇效。
杂谈
前面写很多题的时候,很多时候都看到了动态规划这个思想,不过试着用这个代码跑了跑,花费5512 ms时间。。。太慢了,思路也没怎么看懂,看看以后的题目能不能练一下吧。
"""动态规划"""
class Solution:
def intersect(self, nums1, nums2):
nums1 = sorted(nums1)
nums2 = sorted(nums2)
dp = [[[]] * (len(nums2)+1) for _ in range(len(nums1)+1)]
for i in range(1, len(nums1)+1):
for j in range(1, len(nums2)+1):
if nums1[i-1] == nums2[j-1]:
dp[i][j] = dp[i-1][j-1] + [nums1[i-1]]
else:
dp[i][j] = max(dp[i][j-1], dp[i-1][j], key=len).copy()
return dp[-1][-1]