EasySliding Window

Best Time to Buy and Sell Stock โ€” Solution

Problem

Given an array of daily stock prices, find the maximum profit from a single buy followed by a single sell. You must buy before you sell; if no profitable trade exists, return 0.

Example:

  • Input: prices = [7, 1, 5, 3, 6, 4]
  • Output: 5
  • Explanation: Buy at day 2 (price 1), sell at day 5 (price 6), profit = 6 โˆ’ 1 = 5.

Counter-example: With prices = [7, 6, 4, 3, 1], prices only fall โ€” no profitable trade exists, so return 0.

Intuition

The optimal buy day is always the cheapest price seen before the current day. Scanning left to right while tracking the running minimum lets you compute "best profit if I sell today" in constant time at each step, turning a nested search into a single pass.

Approach 1 โ€” Brute Force

Try every valid buy-sell pair (buy index before sell index) and return the highest profit found.

Steps:

  1. Initialize max_profit = 0.
  2. For each buy_idx from 0 to n โˆ’ 2.
  3. For each sell_idx from buy_idx + 1 to n โˆ’ 1.
  4. Compute profit = prices[sell_idx] - prices[buy_idx].
  5. Update max_profit if profit is larger.
  6. Return max_profit.
1def maxProfit(prices: List[int]) -> int:
2    max_profit = 0
3    for buy_idx in range(len(prices)):
4        for sell_idx in range(buy_idx + 1, len(prices)):
5            profit = prices[sell_idx] - prices[buy_idx]
6            max_profit = max(max_profit, profit)
7    return max_profit
  • Time: O(nยฒ) โ€” every pair of buy and sell days is checked once
  • Space: O(1) โ€” only two integer variables are needed

Approach 2 โ€” One-Pass Minimum Tracking

Scan once, keeping track of the cheapest price seen so far. At each step, the best possible profit if selling today is price - min_price.

Steps:

  1. Initialize min_price = infinity and max_profit = 0.
  2. For each price in prices:
  3. Update min_price to the smaller of min_price and price.
  4. Compute profit = price - min_price and update max_profit if larger.
  5. Return max_profit.
1def maxProfit(prices: List[int]) -> int:
2    min_price = float('inf')
3    max_profit = 0
4    for price in prices:
5        min_price = min(min_price, price)               # track cheapest buy day seen so far
6        max_profit = max(max_profit, price - min_price)
7    return max_profit
  • Time: O(n) โ€” single pass through the array
  • Space: O(1) โ€” two variables regardless of input size

Complexity Summary

ApproachTimeSpaceWhen to use
Brute ForceO(nยฒ)O(1)Only to understand the problem structure; never acceptable in interviews
One-Pass Min TrackingO(n)O(1)Always โ€” optimal for all inputs

Common Mistakes

  • Initializing max_profit to -1 or -infinity โ€” when all prices fall (e.g., [7, 5, 3]), the correct answer is 0 (don't trade). A negative initialization forces a losing trade into the result.
  • Starting the inner brute-force loop at buy_idx instead of buy_idx + 1 โ€” allows buying and selling on the same day; the profit is always 0 so the final answer is unchanged here, but the identical bug silently breaks harder variants like Stock III.
  • Confusing this with "Best Time to Buy and Sell Stock II" โ€” summing every consecutive daily gain is optimal for unlimited transactions but overstates profit here, where only one buy-sell pair is allowed.
  • Sorting the array to find the global minimum and maximum โ€” this destroys the temporal ordering; you must buy before you sell, and the global minimum might appear after the global maximum in the original array.
  • Applying this one-pass pattern to multi-transaction variants โ€” tracking a single running minimum breaks down once two or more transactions are allowed; those variants require DP over a "transactions remaining" state dimension.

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 โ†’