LeetCode 1458. Max Dot Product of Two Subsequences
2020-05-24 21:30:54
# leetcode
Problem
LeetCode 1458. Max Dot Product of Two Subsequences
1. 题目简述
给出两个数组 nums1 和 nums2 。
请返回 nums1 和 nums2 中两个长度相同的 非空 子序列的最大点积。
数组的非空子序列是通过删除原数组中某些元素(可能一个也不删除)后剩余数字组成的序列,但不能改变数字间相对顺序。比方说,[2,3,5] 是 [1,2,3,4,5] 的一个子序列而 [1,5,3] 不是。例如:
Example 1:
Input: nums1 = [2,1,-2,5], nums2 = [3,0,-6]
Output: 18
Explanation: Take subsequence [2,-2] from nums1 and subsequence [3,-6] from nums2.
Their dot product is (2*3 + (-2)*(-6)) = 18.
Example 2:
Input: nums1 = [-1,-1], nums2 = [1,1]
Output: -1
Explanation: Take subsequence [-1] from nums1 and subsequence [1] from nums2.
Their dot product is -1.
Constraints:
1 <= nums1.length, nums2.length <= 500
-1000 <= nums1[i], nums2[i] <= 1000
2. 算法思路
Dynamic Programming
这道题和 LeetCode 72. Edit Distance很类似,今天等下去做一下试试。还有GeekForGeeks的这个Find Maximum dot product of two arrays with insertion of 0’s基本一致。
首先根据数据规模,判断复杂度最多只能是O(mn),不会更多,因此使用DP(做多了应该就一眼看出来了)。
我们设 dp[i][j] 为使用nums1[0 ~ i]和nums2[0 ~ j]的非空子序列的最大点积,那么有如下四种情况。
1. nums1的第i个元素被纳入了最终解中,而nums2的第j个元素没有被纳入最终解中,dp[i][j] = dp[i][j - 1];
2. nums1的第i个元素没有被纳入了最终解中,而nums2的第j个元素被纳入最终解中,dp[i][j] = dp[i - 1][j];
3. nums1的第i个元素和nums2的第j个元素都被纳入到最终解的计算中,dp[i][j] = max(dp[i - 1][j - 1], 0) + nums[i] * nums[j]。
4. nums1的第i个元素和nums2的第j个元素都没有被纳入到最终解的计算中,dp[i][j] = dp[i - 1][j - 1];
但是我们其实会发现,第四种情况根本就是不需要考虑的情况,因为dp[i - 1][j]和dp[i][j - 1]一定是大于等于dp[i - 1][j - 1]的,所以第四种情况我们pass掉,就变成了从三种情况中取最大值。
那么base case是什么样的呢?我们有两种方式进行选择,进行padding或者不进行padding。不进行padding的话可能会多出一些判断条件。padding的意思就是定义一些额外的情况,从而不需要判断边界。
Attention:
这里有几个需要注意的点:
- 首先,这里数字有正有负,所以有可能出现前面dp的值都为负数的情况,所以在上面的第三种情况中,如果我们需要nums[i] * nums[j],则需要判断前面是否小于0,如果小于0,则抛弃前面的dp值。
3. 解法
- Dynamic Programming (with padding)
1 |
|
- Dynamic Programming (without padding)
1 |
|