Problem: 718. 最长重复子数组
暴力
时间复杂度
O
(
n
∗
m
∗
m
i
n
(
m
,
n
)
)
O(n*m*min(m, n))
O(n∗m∗min(m,n)) n,m分别代表两个数组的长度
空间复杂度
O
(
1
)
O(1)
O(1)
class Solution:
def findLength(self, nums1: List[int], nums2: List[int]) -> int:
# 暴力 先找到两个数组相等的位置 然后依次往后判断是否都相等
size1 = len(nums1)
size2 = len(nums2)
ans = 0
for i in range(size1):
for j in range(size2):
# 找到相等的位置
if nums1[i] == nums2[j]:
seq_len = 1 # 公共子数组的长度
while i + seq_len < size1 and j + seq_len < size2 and nums1[i+seq_len] == nums2[j+seq_len]:
seq_len += 1
ans = max(ans, seq_len)
return ans
滑动窗口
暴力的问题是找到两个数组相等的位置需要花费大量的时间,这里面有重叠
滑动窗口:
将两个数组视为两把尺子,固定nums1,nums2的尾部与nums1的头部对齐,移动nums2直到nums2的头部与nums1的尾部对齐,每次滑动只需要计算两个数组重叠部分的子数组的最大公共数组长度即可。

时间复杂度
O
(
n
+
m
)
∗
m
i
n
(
m
,
n
)
)
O(n+m)*min(m, n))
O(n+m)∗min(m,n)) n,m分别代表两个数组的长度
空间复杂度
O
(
1
)
O(1)
O(1)
class Solution:
def findLength(self, nums1: List[int], nums2: List[int]) -> int:
# 滑动窗口,将两个数组视为尺子 固定nums1 不断移动nums2
n1 = len(nums1)
n2 = len(nums2)
def findMaxLength(nums1, nums2, i, j):
cur_len = 0
max_len = 0
while i < n1 and j < n2:
if nums1[i] == nums2[j]:
cur_len += 1
max_len = max(max_len, cur_len)
else:
cur_len = 0
i += 1
j += 1
return max_len
res = 0
# 固定nums1,nums2向左滑动,对应的过程是nums2的头部从左滑动到nums1头部的逆过程
for i in range(n2):
res = max(res, findMaxLength(nums1, nums2, 0, i))
# res = max(res, findMaxLength(nums1, nums2, 0, n2-1-i))
# 也可以写成这样
# 固定nums2,nums1向左滑动,等价于nums2向右滑动,对应的过程是nums2的头部从左滑动到nums1的尾部
for i in range(n1):
res = max(res, findMaxLength(nums1, nums2, i, 0))
return res
本文讨论了如何使用暴力法寻找两个数组的最长重复子数组,以及如何通过滑动窗口算法优化时间复杂度。暴力法的时间复杂度为O(n*m*min(m,n)),而滑动窗口法改进为O(n+m)*min(m,n),同时保持空间复杂度为O(1)。
351

被折叠的 条评论
为什么被折叠?



