class Solution:
def findLength(self, A: List[int], B: List[int]) -> int:
n, m = len(A), len(B)
# dp[i][j]表示A[i:]与B[j:]的最长公共前缀
dp = [[0] * (m + 1) for _ in range(n + 1)]
ans = 0
# 由于用到[i:]、[j:],则从后往前遍历
for i in range(n - 1, -1, -1):
for j in range(m - 1, -1, -1):
# 出现相同的数字才加一
# 否则不是重复子数组,则置为0
dp[i][j] = dp[i + 1][j + 1] + 1 if A[i] == B[j] else 0
ans = max(ans, dp[i][j])
return ans
# 空间优化
def findLength(self, A: List[int], B: List[int]) -> int:
dp = [0] * (len(B) + 1)
result = 0
for i in range(1, len(A)+1):
for j in range(len(B), 0, -1):
if A[i-1] == B[j-1]:
dp[j] = dp[j-1] + 1
else:
dp[j] = 0 #注意这里不相等的时候要有赋0的操作
result = max(result, dp[j])
return result
- 返回最长(公共)重复子数组
def findLength(A, B) -> int:
# dp[j]表示数组B中以下标j结尾的最长公共子数组的长度
dp = [0] * (len(B) + 1)
res = 0
for i in range(1, len(A) + 1):
for j in range(len(B), 0, -1):
# 若当前两个值相等,则最长公共子数组的长度加一
if A[i-1] == B[j-1]:
dp[j] = dp[j-1] + 1
# 若当前两个值不相等,则以下标j结尾的最长公共子数组的长度置为0
else:
dp[j] = 0
# 更新最大公共长度
if res < dp[j]:
res = dp[j]
ans = B[j - res: j]
return res, ans