1 ​​题目​​

  • 注意子数组和子序列的区别
  • 本题如果不加限制就使用动态规划做,很容易变成求最长的子序列的长度

2 思想

使用动态规划解决这个问题。

  • 令​​dp[i,j]​​ 为nums1中前i个数中和nums2中前j个数中最长的重复子数组。
  • 递推公式:
    因为是最长子数组,也就是要求连续,所以​​​dp[i,j]​​​ 的推导一定和​​dp[i-1,j-1]​​​ 紧密联系在一起。 也就是必须要求​​nums1[i-1] == nums2[j-1]​​ 才能保证满足递增。递推公式可以参考下面代码。

3 代码

class Solution:
def findLength(self, nums1: List[int], nums2: List[int]) -> int:
dp = [[0]*len(nums2) for i in range(len(nums1))] # dp[i,j] 表示nums1中以第i个数结尾的数和nums2的第j个结尾数的最大值
l1 = len(nums1)
l2 = len(nums2)
max_res = 0
#初始化
for i in range(l2):
if nums1[0] == nums2[i]:
dp[0][i] = 1
max_res = max(max_res,dp[0][i]) # 更新得到最大值

for i in range(l1):
if nums2[0] == nums1[i]:
dp[i][0] = 1
max_res = max(max_res,dp[i][0]) # 更新得到最大值


for i in range(1,len(nums1)):
for j in range(1,len(nums2)):
if nums1[i] == nums2[j]:
if nums1[i-1] == nums2[j-1]:
dp[i][j] = dp[i-1][j-1] + int(nums1[i]==nums2[j])
else:
dp[i][j] = 1
max_res = max(max_res,dp[i][j]) # 更新得到最大值
# print(dp)
return max_res