Return the maximum dot product between non-empty subsequences of nums1 and nums2 with the same length.
A subsequence of a array is a new array which is formed from the original array by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, [2,3,5] is a subsequence of [1,2,3,4,5] while [1,5,3] is not).
Input: nums1 =[2,1,-2,5], nums2 =[3,0,-6]Output: 18Explanation: Take subsequence [2,-2] from nums1 and subsequence [3,-6] from nums2.Their dot product is(2*3+(-2)*(-6))=18.
Input: nums1 =[3,-2], nums2 =[2,-6,7]Output: 21Explanation: Take subsequence [3] from nums1 and subsequence [7] from nums2.Their dot product is(3*7)=21.
We use a 2D DP table to track the maximum dot product for all pairs of prefixes of nums1 and nums2. At each step, we can either take both elements, skip one from nums1, or skip one from nums2. We must ensure at least one pair is chosen.
funcmaxDotProduct(nums1 []int, nums2 []int) int {
m, n:= len(nums1), len(nums2)
dp:= make([][]int, m)
fori:=rangedp {
dp[i] = make([]int, n)
forj:=rangedp[i] {
dp[i][j] = -1<<30 }
}
fori:=0; i < m; i++ {
forj:=0; j < n; j++ {
prod:=nums1[i] *nums2[j]
dp[i][j] = max(prod, prod+max(0, get(dp, i-1, j-1)), get(dp, i-1, j), get(dp, i, j-1))
}
}
returndp[m-1][n-1]
}
funcget(dp [][]int, i, jint) int {
ifi < 0||j < 0 {
return-1<<30 }
returndp[i][j]
}
func max(a...int) int {
ans:=a[0]
for_, v:=rangea {
ifv > ans {
ans = v }
}
returnans}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
classSolution {
publicintmaxDotProduct(int[] nums1, int[] nums2) {
int m = nums1.length, n = nums2.length;
int[][] dp =newint[m][n];
for (int i = 0; i < m; ++i)
Arrays.fill(dp[i], Integer.MIN_VALUE);
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
int prod = nums1[i]* nums2[j];
dp[i][j]= Math.max(prod, Math.max(prod + Math.max(0, (i > 0 && j > 0 ? dp[i-1][j-1] : 0)),
Math.max(i > 0 ? dp[i-1][j] : Integer.MIN_VALUE,
j > 0 ? dp[i][j-1] : Integer.MIN_VALUE)));
}
}
return dp[m-1][n-1];
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
classSolution {
funmaxDotProduct(nums1: IntArray, nums2: IntArray): Int {
val m = nums1.size
val n = nums2.size
val dp = Array(m) { IntArray(n) { Int.MIN_VALUE } }
for (i in0 until m) {
for (j in0 until n) {
val prod = nums1[i] * nums2[j]
dp[i][j] = maxOf(prod,
prod + maxOf(0, if (i > 0&& j > 0) dp[i-1][j-1] else0),
if (i > 0) dp[i-1][j] elseInt.MIN_VALUE,
if (j > 0) dp[i][j-1] elseInt.MIN_VALUE)
}
}
return dp[m-1][n-1]
}
}
1
2
3
4
5
6
7
8
9
10
11
12
classSolution:
defmaxDotProduct(self, nums1: list[int], nums2: list[int]) -> int:
m, n = len(nums1), len(nums2)
dp = [[float('-inf')] * n for _ in range(m)]
for i in range(m):
for j in range(n):
prod = nums1[i] * nums2[j]
dp[i][j] = max(prod,
prod + max(0, dp[i-1][j-1] if i >0and j >0else0),
dp[i-1][j] if i >0else float('-inf'),
dp[i][j-1] if j >0else float('-inf'))
return dp[m-1][n-1]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
impl Solution {
pubfnmax_dot_product(nums1: Vec<i32>, nums2: Vec<i32>) -> i32 {
let m = nums1.len();
let n = nums2.len();
letmut dp =vec![vec![i32::MIN; n]; m];
for i in0..m {
for j in0..n {
let prod = nums1[i] * nums2[j];
dp[i][j] = prod.max(prod + dp.get(i.wrapping_sub(1)).and_then(|row| row.get(j.wrapping_sub(1))).copied().unwrap_or(0).max(0))
.max(dp.get(i.wrapping_sub(1)).and_then(|row| row.get(j)).copied().unwrap_or(i32::MIN))
.max(dp.get(i).and_then(|row| row.get(j.wrapping_sub(1))).copied().unwrap_or(i32::MIN));
}
}
dp[m-1][n-1]
}
}