Maximum Multiplication Score
MEDIUMDescription
You are given an integer array a of size 4 and another integer array b of size at least 4.
You need to choose 4 indices i0, i1, i2, and i3 from the array b such that i0 < i1 < i2 < i3. Your score will be equal to the value a[0] * b[i0] + a[1] * b[i1] + a[2] * b[i2] + a[3] * b[i3].
Return the maximum score you can achieve.
Example 1:
Input: a = [3,2,5,6], b = [2,-6,4,-5,-3,2,-7]
Output: 26
Explanation:
We can choose the indices 0, 1, 2, and 5. The score will be 3 * 2 + 2 * (-6) + 5 * 4 + 6 * 2 = 26.
Example 2:
Input: a = [-1,4,5,-2], b = [-5,-1,-3,-2,-4]
Output: -1
Explanation:
We can choose the indices 0, 1, 3, and 4. The score will be (-1) * (-5) + 4 * (-1) + 5 * (-2) + (-2) * (-4) = -1.
Constraints:
a.length == 44 <= b.length <= 105-105 <= a[i], b[i] <= 105
Approaches
Checkout 3 different approaches to solve Maximum Multiplication Score. Click on different approaches to view the approach and algorithm in detail.
Dynamic Programming with O(N) Space
A more efficient solution uses dynamic programming. The problem has optimal substructure and overlapping subproblems. We can build the solution iteratively. We first find the maximum scores possible by choosing one element, then use those results to find the maximum scores for choosing two elements, and so on, up to four elements.
Algorithm
- Define
dp[k][i]as the maximum score using the firstkelements ofaandkelements chosen from the prefixb[0...i]. - The state transition is
dp[k][i] = max(dp[k][i-1], dp[k-1][i-1] + a[k-1] * b[i]). dp[k][i-1]corresponds to not pickingb[i].dp[k-1][i-1] + a[k-1] * b[i]corresponds to pickingb[i]as the k-th element.- Since
dp[k]only depends ondp[k-1], we can optimize space from O(k*N) to O(N) by using two arrays:prev_dpfor stagek-1andcurr_dpfor stagek. - Initialize a
dparray of sizenfor thek=1case. - Iterate
kfrom 2 to 4, calculating thedpvalues for the current stage using the values from the previous stage. - The final answer is the last element of the
dparray after computing fork=4.
Let's define dp[k][i] as the maximum score using a[0]...a[k-1] and k elements from b chosen from the prefix b[0...i]. The recurrence relation captures the two choices at each step i for each number of elements k: either we include b[i] as the k-th element or we don't.
dp[k][i] = max(dp[k][i-1], dp[k-1][i-1] + (long)a[k-1] * b[i])
This would typically require a 2D DP table of size 4 x N. However, we can observe that to compute the values for k elements, we only need the results for k-1 elements. This allows for a space optimization where we only need to store the DP results for the previous k and the current k, reducing space to O(N).
class Solution {
public long maximumMultiplicationScore(int[] a, int[] b) {
int n = b.length;
long[] dp = new long[n];
// k = 1
dp[0] = (long) a[0] * b[0];
for (int i = 1; i < n; i++) {
dp[i] = Math.max(dp[i - 1], (long) a[0] * b[i]);
}
// k = 2 to 4
for (int k = 1; k < 4; k++) {
long[] prev_dp = dp;
dp = new long[n];
// We need at least k elements (0-indexed)
// so the first possible score is at index k.
// dp[k] = prev_dp[k-1] + a[k]*b[k]
// Initialize dp[k-1] to a very small value to handle the max correctly.
dp[k-1] = Long.MIN_VALUE;
for (int i = k; i < n; i++) {
long pick_b_i = prev_dp[i - 1] + (long) a[k] * b[i];
long not_pick_b_i = dp[i - 1];
dp[i] = Math.max(pick_b_i, not_pick_b_i);
}
}
return dp[n - 1];
}
}
Complexity Analysis
Pros and Cons
- Efficient linear time complexity, which passes the given constraints.
- Conceptually builds upon a standard DP pattern.
- Requires linear space, which could be a limitation if memory is highly constrained, though it's acceptable for this problem's constraints.
Code Solutions
Checking out 3 solutions in different languages for Maximum Multiplication Score. Click on different languages to view the code.
class Solution {
private
Long[][] f;
private
int[] a;
private
int[] b;
public
long maxScore(int[] a, int[] b) {
f = new Long[a.length][b.length];
this.a = a;
this.b = b;
return dfs(0, 0);
}
private
long dfs(int i, int j) {
if (j >= b.length) {
return i >= a.length ? 0 : Long.MIN_VALUE / 2;
}
if (i >= a.length) {
return 0;
}
if (f[i][j] != null) {
return f[i][j];
}
return f[i][j] =
Math.max(dfs(i, j + 1), 1L * a[i] * b[j] + dfs(i + 1, j + 1));
}
}
Video Solution
Watch the video walkthrough for Maximum Multiplication Score
Similar Questions
5 related questions you might find useful
Patterns:
Data Structures:
Subscribe to Scale Engineer newsletter
Learn about System Design, Software Engineering, and interview experiences every week.
No spam, unsubscribe at any time.