Intuition
- To solve the problem brute force, notice that each stock, if bought at that time, can be compared with each subsequent stock, getting the max of the positive difference between the stock bought and sold.
- This same brute force solution can be solved recursively in a top down fashion (Dynamic Programming (Coding)).
- Each stock bought relies on information in the future to determine the optimal cost if making the decision to buy then.
- For each index i, you have the choice:
- Buy at that stock
- If bought previously, sell
- Buy at next stock
- However, this will give a memory limit exceeded error since 2 recursive calls are made for each i.
- For bottom up,
- The optimal solution is to use Sliding Window. Sliding window works here since as long as a previous stock is greater than or equal to a later stock, it cannot be sold for profit. So, via a sliding window, skip such combinations.
- Also, if an left and right, left right combination is valid, the array in question must be increasing (since otherwise you would encounter a value greater than or equal to prices[right])
- ex) [2, 3, 4, 1, 5, 6]
- Anything less than 2 must be encountered via the window.
- ex) [2, 3, 4, 1, 5, 6]
Complexity
Runtime
since there are at most 2N iterations
Space
Code
DP
Bottom Up
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if not prices:
return 0
n = len(prices)
min_price = prices[0]
max_profit = 0
for i in range(1, n):
# Update max_profit if selling today is better than any previous day
max_profit = max(max_profit, prices[i] - min_price)
# Update min_price if today's price is lower than any seen before
min_price = min(min_price, prices[i])
return max_profitMLE Top Down
class Solution:
def maxProfit(self, prices: List[int]) -> int:
n = len(prices)
@cache
def r(i, bought_price):
if i >= n:
return 0
# Buy on next instead, sell, sell on next, bad sale
return max(r(i + 1, prices[i]), prices[i] - bought_price, r(i + 1, bought_price), 0)
return r(0, prices[0])Sliding Window
class Solution:
def maxProfit(self, prices: List[int]) -> int:
n = len(prices)
res = 0
left = 0
for right in range(n):
while left < right and prices[left] >= prices[right]:
left += 1
res = max(res, prices[right] - prices[left])
return resTLE
class Solution:
def maxProfit(self, prices: List[int]) -> int:
res = 0
n = len(prices)
for i in range(n):
top = max(prices[i + 1:], default=0)
res = max(res, top - prices[i])
return resNotes
Cards
START Basic Front: Best Time To Buy And Sell Stock Back: END