I was solving LeetCode problem 3290. Maximum Multiplication Score:
You are given an integer array
aof size 4 and another integer arraybof size at least 4.You need to choose 4 indices
i0, i1, i2, and i3from the arraybsuch thati0 < i1 < i2 < i3. Your score will be equal to the valuea[0] * b[i0] + a[1] * b[i1] + a[2] * b[i2] + a[3] * b[i3].Return the maximum score you can achieve.
Example:
Input:
a = [3,2,5,6], b = [2,-6,4,-5,-3,2,-7]Output: 26
Explanation: Choose indices 0, 1, 2, and 5 from
b.
My Attempt:
I wrote two recursive + memoization solutions, but one of them exceeds the given time limit ("Time Limit Exceeded" TLE) for larger n. Here are the two approaches:
Solution 1 (TLE)
class Solution:
def maxScore(self, a, b):
def dfs(i, j):
if i == len(a): # All elements in `a` processed
return 0
if (i, j) in memo: # Return memoized result
return memo[(i, j)]
max_result = float("-inf")
for index in range(j, len(b)):
if len(b) - index < len(a) - i: # Not enough elements left in `b`
break
max_result = max(max_result, a[i] * b[index] + dfs(i + 1, index + 1))
memo[(i, j)] = max_result
return max_result
memo = {}
return dfs(0, 0)
Solution 2 (Works)
class Solution:
def maxScore(self, a, b):
def dfs(i, picked):
if picked == 4: # All elements in `a` processed
return 0
if len(b) - i + picked < 4: # Not enough elements left in `b`
return float("-inf")
if (i, picked) in memo: # Return memoized result
return memo[(i, picked)]
pick = a[picked] * b[i] + dfs(i + 1, picked + 1) # Pick this index
skip = dfs(i + 1, picked) # Skip this index
memo[(i, picked)] = max(pick, skip)
return memo[(i, picked)]
memo = {}
return dfs(0, 0)
Question:
Why does Solution 1 lead to TLE while Solution 2 works efficiently? I think without the memoization both the solutions will have the same time complexity of O(2^n) of pick or not pick, but I can't pinpoint why the pruning or memoization doesn't seem to help as much as in Solution 2. Could someone provide a detailed explanation?