You are given an array
priceswhereprices[i]is the price of a given stock on theithday.You want to maximise your profit by choosing a single day to buy one stock and choosing a different day in the future to sell that stock.
Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return
0.Constraints:
- 1 <= prices.length <= 105
- 0 <= prices[i] <= 104
Let represent buying on day and selling on day , and be the price on day . The brute force solution requires us to check every pair and calculate the maximum profit from that. We can reduce the solution space, however, if we consider a few insights:
We can thus start our search from the indices —buy on the first day, and sell on the next. If there is a profit, then we can check selling on the subsequent day, , and so on.
In general, if results in a loss, why don’t we need to check for some and can move straight to checking ? Since the algorithm has moved the selling day past to , that means that has resulted in a profit—in other words, . Since is a loss, we have . Thus, , so always underperforms compared to .
j in the loop, the profit at for any is bigger than for any .def maxProfit(self, prices: List[int]) -> int:
buy = 0
max_profit = 0
for sell in range(1, len(prices)):
profit = prices[sell] - prices[buy]
if profit < 0:
# (sell, k) always outperforms (buy, k) for subsequent k
buy = sell
else:
# update max_profit if needed; otherwise, keep checking
max_profit = max(max_profit, profit)
return max_profit
Another way to think about this is that we always buy at the lowest price we have seen. Notice that checking if profit < 0 is the same thing as checking if prices[sell] < prices[buy]. If so, we update buy = sell. And since buying at the lowest price will outperform buying at any other price seen before, we won’t miss any bigger trades.
Notice the while loop is dependant on the value of sell, and not buy, and that sell always increments by 1 at every iteration. Therefore, a maximum of iterations are performed, so the algorithm has a worst case runtime in .
We don’t store any complex structures—the only variables declared are constant integers, so the space complexity is constant—.