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