📅  最后修改于: 2023-12-03 15:40:14.526000             🧑  作者: Mango
给定两个长度相等的整数数组 nums1
和 nums2
,请找到各自数组中所选索引的相同子数组,并使这些子数组中的数字之和最大化。在选定的子数组中,可以同时选择 nums1 和 nums2 中的元素,但是不能同时选择两个数组中的相同索引位置上的元素。
这是一个典型的动态规划问题。设 $dp[i][j]$ 表示包含 nums1[i]
和 nums2[j]
的相同子数组的最大和。考虑 nums1[i]
和 nums2[j]
是否应该包含在相同子数组中:
nums1[i]
,也包含 nums2[j]
,即 $dp[i][j]=dp[i-1][j-1]+nums1[i] = dp[i-1][j-1]+nums2[j]$。综上可得状态转移方程:
$$ dp[i][j]= \begin{cases} 0, & i=0 \text{ or } j=0 \ \max(dp[i-1][j], dp[i][j-1]), & nums1[i] \neq nums2[j]\ dp[i-1][j-1]+nums1[i], & nums1[i]=nums2[j] \end{cases} $$
根据状态转移方程,初始化 $dp$ 数组,然后按照顺序填充每个 $dp[i][j]$,最后返回 $dp[n-1][n-1]$ 即可。
以下是使用 Python 实现上述动态规划算法的代码:
def maxSum(nums1: List[int], nums2: List[int]) -> int:
n = len(nums1)
dp = [[0] * n for _ in range(n)]
dp[0][0] = nums1[0] if nums1[0] == nums2[0] else 0
for i in range(1, n):
dp[i][0] = nums1[i] if nums1[i] == nums2[0] else max(dp[i-1][0], 0)
dp[0][i] = nums2[i] if nums1[0] == nums2[i] else max(dp[0][i-1], 0)
for i in range(1, n):
for j in range(1, n):
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
if nums1[i] == nums2[j]:
dp[i][j] = max(dp[i][j], dp[i-1][j-1] + nums1[i])
return dp[n-1][n-1]
时间复杂度 $O(n^2)$:填充 $dp$ 数组的时间复杂度为 $O(n^2)$。
空间复杂度 $O(n^2)$:使用了一个 $n \times n$ 的 $dp$ 数组。