MediumArrays & Hashing

Best Time to Buy and Sell Stock II โ€” Solution

Problem

You have a list of daily stock prices and can make as many buy/sell transactions as you want โ€” but you can hold at most one share at a time. Find the maximum total profit you can earn.

  • Input: prices = [7, 1, 5, 3, 6, 4]
  • Output: 7
  • Explanation: Buy at 1 (day 2), sell at 5 (day 3) for profit 4; buy at 3 (day 4), sell at 6 (day 5) for profit 3; total = 7.

Counter-example: prices = [7, 6, 4, 3, 1] โ†’ output 0 โ€” prices only fall, so no trade is profitable.

Intuition

Any valley-to-peak gain can be split into consecutive day-over-day gains without losing any total profit. Instead of finding the perfect buy and sell windows, you can simply collect every day where the price rises. This reduces the problem to a single linear scan with no state tracking at all.

Solution โ€” Greedy Day-Over-Day Scan

Scan adjacent day pairs and accumulate every positive price difference; skip days where the price falls.

  1. Initialize total_profit to 0.
  2. Loop through days starting from the second day (index 1).
  3. If today's price exceeds yesterday's, add the difference to total_profit.
  4. Return total_profit.
1def maxProfit(prices: list[int]) -> int:
2    total_profit = 0
3    for i in range(1, len(prices)):
4        # every upward move is a profitable trade worth capturing
5        if prices[i] > prices[i - 1]:
6            total_profit += prices[i] - prices[i - 1]
7    return total_profit

Time: O(n) โ€” single pass through the prices array.
Space: O(1) โ€” only a running total is stored.

Complexity Summary

ApproachTimeSpaceWhen to use
Greedy Day-Over-Day ScanO(n)O(1)Any time unlimited transactions are permitted

Common Mistakes

  • Tracking min_price like in Stock I โ€” Stock I needs the historical minimum because you get exactly one buy opportunity; here each transaction is independent so past price minimums are irrelevant and only the previous day matters.
  • Hunting for valley-peak pairs with nested loops โ€” finding local minima and maxima works but is unnecessarily complex; the greedy proves that the sum of all positive consecutive differences within a rising run equals the run's total valley-to-peak gain.
  • Treating the problem as strict alternating buy/sell cycles โ€” you don't need to track a holding boolean or toggle between buy/sell modes; scanning for positive daily moves captures all profit without managing transaction state.
  • Starting the iteration at index 0 โ€” comparing prices[i] with prices[i - 1] at i = 0 accesses prices[-1] in Python (wraps to the last element, giving a wrong result) and throws ArrayIndexOutOfBoundsException in Java; always start at index 1.
  • Returning a negative value when prices only fall โ€” an approach that blindly computes prices.last - prices.first would return a negative profit; the greedy naturally returns 0 for a monotonically decreasing array since no condition prices[i] > prices[i - 1] is ever true.

Related Problems

Ready to practice? Try it on SkillFlow

Adaptive problems, AI follow-up interviews, and a skill score that shows exactly where you need to improve.

Practice This Problem โ†’