A clear explanation of maximizing stock profit with unlimited transactions using a greedy single-pass method.
Problem Restatement
We are given an array prices, where prices[i] is the stock price on day i.
We may buy and sell the stock multiple times, but we can hold at most one share at a time. That means we must sell before buying again.
We need to return the maximum profit possible.
For example:
prices = [7, 1, 5, 3, 6, 4]The best strategy is:
buy at 1, sell at 5 -> profit 4
buy at 3, sell at 6 -> profit 3Total profit:
4 + 3 = 7So the answer is:
7Input and Output
| Item | Meaning |
|---|---|
| Input | List of stock prices |
| Output | Maximum total profit |
| Transaction count | Unlimited |
| Holding rule | At most one share at a time |
| Same-day action | You may sell and buy again on the same day |
| No profit case | Return 0 |
The function shape is:
class Solution:
def maxProfit(self, prices: list[int]) -> int:
...Examples
For:
prices = [7, 1, 5, 3, 6, 4]We collect the increasing parts:
1 -> 5 gives 4
3 -> 6 gives 3Total:
7For:
prices = [1, 2, 3, 4, 5]The price rises every day.
We can buy at 1 and sell at 5, giving profit 4.
Equivalently, we can take every daily increase:
1 -> 2 gives 1
2 -> 3 gives 1
3 -> 4 gives 1
4 -> 5 gives 1Total:
4For:
prices = [7, 6, 4, 3, 1]The price only decreases, so no profitable transaction exists.
The answer is:
0First Thought: Find Every Buy-Sell Pair
Because multiple transactions are allowed, we might try every possible sequence of buys and sells.
But that becomes complicated. We would need to decide:
- when to buy,
- when to sell,
- when to skip,
- how to combine transactions.
A simpler observation gives the answer directly.
Key Insight
Every positive daily price difference can be taken as profit.
If today’s price is higher than yesterday’s price, then this increase can contribute to the answer:
prices[i] - prices[i - 1]when it is positive.
For example:
prices = [1, 5, 3, 6]The profitable increases are:
1 -> 5 gives 4
3 -> 6 gives 3Total profit:
7This matches the best strategy:
buy at 1, sell at 5
buy at 3, sell at 6For a longer increasing run:
[1, 2, 3, 4, 5]taking every small increase gives:
(2 - 1) + (3 - 2) + (4 - 3) + (5 - 4) = 4which is the same as:
5 - 1 = 4So we do not need to locate exact valleys and peaks. Adding all positive adjacent differences is enough.
Algorithm
Initialize:
profit = 0Then scan the array from day 1 to the end.
For each day i:
- If
prices[i] > prices[i - 1], add the difference toprofit. - Otherwise, skip it.
Return profit.
Correctness
Any profitable transaction from a buy day b to a sell day s has profit:
prices[s] - prices[b]This difference can be decomposed into adjacent daily differences:
(prices[b + 1] - prices[b])
+ (prices[b + 2] - prices[b + 1])
+ ...
+ (prices[s] - prices[s - 1])If an adjacent difference is positive, taking it increases total profit. If it is zero or negative, taking it would not help.
Since we may perform multiple transactions and hold at most one share at a time, every positive adjacent increase can be realized by buying before the increase and selling after it.
Therefore, summing all positive adjacent increases gives a valid trading strategy.
No strategy can do better, because every buy-sell profit is made from the same adjacent differences, and negative differences can only reduce profit. The maximum possible total profit is exactly the sum of all positive adjacent differences.
Complexity
| Metric | Value | Why |
|---|---|---|
| Time | O(n) | We scan the prices once |
| Space | O(1) | We store only the profit variable |
Implementation
class Solution:
def maxProfit(self, prices: list[int]) -> int:
profit = 0
for i in range(1, len(prices)):
if prices[i] > prices[i - 1]:
profit += prices[i] - prices[i - 1]
return profitCode Explanation
Start with zero profit:
profit = 0Scan from the second day:
for i in range(1, len(prices)):If today’s price is higher than yesterday’s price:
if prices[i] > prices[i - 1]:then we add that increase:
profit += prices[i] - prices[i - 1]Finally:
return profitTesting
class Solution:
def maxProfit(self, prices: list[int]) -> int:
profit = 0
for i in range(1, len(prices)):
if prices[i] > prices[i - 1]:
profit += prices[i] - prices[i - 1]
return profit
def run_tests():
s = Solution()
assert s.maxProfit([7, 1, 5, 3, 6, 4]) == 7
assert s.maxProfit([1, 2, 3, 4, 5]) == 4
assert s.maxProfit([7, 6, 4, 3, 1]) == 0
assert s.maxProfit([1]) == 0
assert s.maxProfit([2, 1, 2, 0, 1]) == 2
print("all tests passed")
run_tests()Test meaning:
| Test | Why |
|---|---|
[7,1,5,3,6,4] | Standard multiple-transaction case |
[1,2,3,4,5] | One long increasing run |
[7,6,4,3,1] | No profit possible |
| Single price | Cannot sell after buying |
| Mixed rises and drops | Confirms only positive adjacent differences are counted |