1458. 两个子序列的最大点积
大约 3 分钟
---
1458. 两个子序列的最大点积
- 标签:数组、动态规划
- 难度:困难
题目链接
题目大意
描述:给定两个数组 和 。
要求:返回两个长度相等的非空子序列的最大点积。点积定义为对应位置元素的乘积之和。
说明:
- 。
- 。
示例:
- 示例 1:
输入:nums1 = [2,1,-2,5], nums2 = [3,0,-6]
输出:18
解释:从 nums1 中得到子序列 [2,-2] ,从 nums2 中得到子序列 [3,-6] 。
它们的点积为 (2*3 + (-2)*(-6)) = 18 。- 示例 2:
输入:nums1 = [3,-2], nums2 = [2,-6,7]
输出:21
解释:从 nums1 中得到子序列 [3] ,从 nums2 中得到子序列 [7] 。
它们的点积为 (3*7) = 21 。解题思路
思路 1:二维 DP
1. 核心思想
定义 表示 前 个元素和 前 个元素中,能得到的最大点积(至少选一组对阵)。
2. 阶段划分
按 和 作为阶段,从 递增。
3. 定义状态
:考虑 和 ,能得到的最大点积。
4. 状态转移方程
对于 ,有几个选择:
- 不选 :
- 不选 :
- 不选两个:(事实上被前两种覆盖)
- 选这一对:
- 只选这一对(前面都不选):
5. 初始条件
,。
6. 最终结果
。
7. 举例说明
以 为例:
...逐步递推...
最终最大点积为 (取 等)。
等等,让我重新计算:,,,,。
实际上最优可能是 或 或 。但 ? 是 , 是 ,,这就是最大点积。
思路 1:代码
class Solution:
def maxDotProduct(self, nums1: List[int], nums2: List[int]) -> int:
n, m = len(nums1), len(nums2)
dp = [[float('-inf')] * (m + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
for j in range(1, m + 1):
product = nums1[i - 1] * nums2[j - 1]
# 四种情况取最大值
dp[i][j] = max(
dp[i - 1][j],
dp[i][j - 1],
dp[i - 1][j - 1] + product,
product
)
return dp[n][m]思路 1:复杂度分析
- 时间复杂度:。
- 空间复杂度:,可优化为 。