Finish at price 4On day 5, profit 4-1=3 cannot beat 5; buy day 1 and sell day 4 remain optimal.
70lowest earlier buy11523364selling day45
scannedPrefix[0..5]arithmeticlowest=1; profit=4-1=3; best=5result5 (buy day 1 at 1; sell day 4 at 6)
Recognize it
Use a running minimum when an ordered one-pass problem asks for the best later-minus-earlier difference and the buy or baseline must occur before the current item.
Keep true
After each day, lowest is the minimum price in the scanned prefix and best is the largest valid sell-minus-earlier-buy profit whose selling day lies in that prefix.
Reuse it
For maximum ordered differences, summarize the best earlier baseline while treating each new value as the right endpoint; analogous scans find maximum rise, minimum spread, and best prefix-relative gain.
Read it this way: On day 0 price 7, lowest=min(infinity,7)=7 and best=max(0,7-7)=0. Step through the frames to watch the state change. The last frame shows the answer or the stopping condition.
Pattern: Running minimum.
Simple idea: For each selling price, the best earlier buy is the lowest price seen so
far. Update that lowest price and the best profit as you scan.
def max_profit(prices: list[int]) -> int: lowest = float("inf") best = 0 for price in prices: lowest = min(lowest, price) best = max(best, price - lowest) return best