📖 9 min read
Last updated on

Best Time to Buy and Sell Stock — Coding Interview Walkthrough


Hero Image for Best Time To Buy And Sell Stock

You’re in a coding interview. The interviewer pulls up a problem you’ve seen before: “Given daily stock prices, find the maximum profit from a single buy-sell transaction.” It’s Best Time to Buy and Sell Stock, one of the most common warm-up problems at Amazon, Google, and Meta. You know the answer involves tracking a minimum, but now you need to explain why the greedy approach works, handle follow-ups about edge cases, and articulate the jump from O(n²) to O(n) while someone watches.

This walkthrough covers how that conversation unfolds: the clarifying questions that set you apart, the brute-force-to-optimal progression interviewers want to see, and the follow-up variants that turn a warm-up into a deeper conversation.


The Problem

You’re given an array prices where prices[i] represents the price of a stock on day i. You want to maximize your profit by choosing one day to buy and a later day to sell. If no profit is possible, return 0. (LeetCode #121)

Example

Input

prices = [7, 1, 5, 3, 6, 4, "easy"]

Output

5

Explanation: On day 2 the price is 1 (buy), and on day 5 the price is 6 (sell), yielding a profit of 6 - 1 = 5. Note that buying on day 2 and selling on day 1 is not allowed. You must buy before you sell. The maximum single-transaction profit is 5, not 7 (which would require selling before buying).

Already comfortable with the solution? Practice it in a mock interview →


What Interviewers Are Actually Testing

The problem might sound like a simple max/min exercise, but interviewers use it to probe several distinct skills simultaneously. The brevity of the optimal solution makes communication especially important. A five-line answer needs to be explained well to impress.

SkillWhat Interviewers Observe
Constraint recognitionDo you catch “buy before sell” immediately?
Greedy intuitionCan you reason about local vs. global optima?
Optimization instinctDo you move naturally from O(n²) to O(n)?
Edge case awarenessDo you handle all-decreasing prices and single-element arrays?
Communication clarityCan you explain a simple algorithm without over-complicating it?
Follow-up readinessCan you extend the solution to multiple transactions (LeetCode #122)?

Step 1 — Clarifying Questions

Even for an Easy-rated problem, taking 60 seconds to ask smart questions signals maturity. Here are the most valuable ones:

  • Can I make multiple transactions, or only one buy-sell pair? The problem specifies exactly one transaction, but confirming this shows you’re aware the problem has harder variants. It also sets up a natural follow-up conversation.

  • Should I return 0 if no profit is possible, or indicate an error? The problem guarantees returning 0 for the no-profit case, but confirming this shows you’ve thought about negative/flat price arrays.

  • Can prices be negative, or are they guaranteed positive? Stock prices are typically positive, but clarifying input constraints is a good habit, especially if you were to generalize this to other domains.

  • Is the array guaranteed to be non-empty? An empty array would make the problem ill-defined. Asking this shows defensive programming instincts and leads naturally to discussing edge cases.

  • Do I need to return the buy and sell days, or just the maximum profit? The problem only asks for the profit value, but some interview variants ask for the actual days. Confirming upfront avoids building the wrong output.


Step 2 — A First (Non-Optimal) Idea

The most natural first approach is to check every possible buy-sell pair: for every day i, consider selling on every day j > i and track the maximum difference.

def maxProfit(prices):
    max_profit = 0
    for i in range(len(prices)):
        for j in range(i + 1, len(prices)):
            profit = prices[j] - prices[i, "easy"]
            max_profit = max(max_profit, profit)
    return max_profit

This is correct and readable. For an array of 100,000 days (well within LeetCode’s constraints), this approach would perform up to 5 billion comparisons, which is clearly unacceptable.

ApproachTime ComplexitySpace Complexity
Brute force (nested loops)O(n²)O(1)

Always narrate the tradeoff: “This works but doesn’t scale. I’d like to see if I can reduce this to a single pass.”


Step 3 — The Key Insight

You don’t need to compare every pair. You just need to track the lowest price you’ve seen so far. As you scan left to right, ask yourself: “If I were forced to sell today, what’s the best I could do?” The answer is always: sell at today’s price, having bought at the cheapest price seen before today.

This reframes the problem from “find the best pair” to “at each step, compute the best possible profit if I sell right now.” You only need two variables:

  • min_price: the lowest price encountered so far (the best day to have bought)
  • max_profit: the best profit seen so far

At each step, you update both. No pair-comparison needed. The key constraint, “buy before sell,” is naturally satisfied because you’re always looking backward at the minimum.

Price array [7,1,5,3,6,4] with buy pointer at price 1 (green), sell pointer at price 6 (amber), and bracket showing profit = 6 − 1 = 5. ---

Step 4 — Optimal Strategy

  1. Initialize min_price to positive infinity (or prices[0]), since you haven’t seen any price yet.
  2. Initialize max_profit to 0, since no transaction means no profit.
  3. Iterate through each price in prices.
  4. If the current price is lower than min_price, update min_price.
  5. Otherwise, compute current_profit = price - min_price.
  6. If current_profit exceeds max_profit, update max_profit.
  7. After the loop, return max_profit.

The order of steps 4 and 5 is important: you check whether to update the minimum before computing profit, which correctly prevents buying and selling on the same day.


Python Implementation

def maxProfit(prices: list[int]) -> int:
    min_price = float('inf')  # Best buying price seen so far
    max_profit = 0            # Best profit achievable so far

    for price in prices:
        if price < min_price:
            # Found a cheaper day to buy, so update our reference point
            min_price = price
        else:
            # What's the profit if we sell today?
            current_profit = price - min_price
            max_profit = max(max_profit, current_profit)

    return max_profit

Why this is interview-friendly:

  • Using float('inf') as the initial min_price is more robust than prices[0], since it handles edge cases like an empty array without an index error.
  • The variable names min_price and max_profit communicate intent without needing comments.
  • The else branch makes the logic explicit: you’re either updating your buy point or evaluating a potential sale, never both in the same step.

Time & Space Complexity

OperationComplexity
Iterating through the arrayO(n)
Each comparison/assignmentO(1)
Overall timeO(n)
Space (two variables)O(1)

Time: We iterate through the array exactly once. Each step involves a constant number of comparisons and assignments.

Space: We use only two variables regardless of input size — this is optimal. Unlike the Two Sum hash map solution, there’s no space tradeoff here. We get both O(n) time and O(1) space.

This is worth emphasizing in an interview: “This is about as efficient as it gets: linear time and constant space.”


Common Interview Mistakes

  • Selling before buying. Iterating through all pairs without enforcing j > i is the most common brute-force bug. Always verify that your buy day precedes your sell day.

  • Initializing min_price to 0. Zero seems like a safe default, but if all prices are positive (which they are for stocks), this would cause min_price to never update. Use float('inf') or prices[0].

  • Returning a negative profit. If prices only decrease (e.g., [7, 6, 4, 3, 1]), the correct answer is 0. You simply don’t trade. Forgetting to initialize max_profit = 0 and instead returning the least-negative difference is a subtle but wrong answer.

  • Confusing this with the “maximum subarray” problem. Kadane’s algorithm solves a related but different problem. While you can convert Buy and Sell Stock into a max subarray problem using price differences, jumping straight there without explanation confuses interviewers who want to see your greedy reasoning.

  • Not handling a single-element array. If prices = [5], you can’t make any transaction. Your solution should return 0 naturally, so verify this with your initialization choices.

  • Coding without explaining the greedy insight. The implementation is short, which means the verbal explanation carries more weight. Candidates who type the solution silently and then say “done” leave the interviewer with nothing to evaluate.

  • Not mentioning follow-up variants. Proactively noting that this problem has harder siblings (unlimited transactions, at most k transactions, with cooldown) shows breadth and invites a richer interview conversation.


What a Strong Candidate Sounds Like

“Let me start by clarifying: we can only make one buy and one sell, and we need to buy before we sell. If no profit is possible, we return zero.

My first instinct is a nested loop to compare every buy-sell pair. That’s O(n²), which works but doesn’t scale. I think I can do this in one pass.

The key insight is: as I scan left to right, I just need to track the cheapest price I’ve seen so far. At every step, I ask, if I sell today, what’s my profit? That’s today’s price minus the minimum so far. I keep track of the best such profit as I go. Since I’m always looking backward for the minimum, I can never sell before I buy.

This gives me O(n) time and O(1) space, which is optimal. Let me code it up.”


Example Interview Dialogue

Interviewer: Walk me through Best Time to Buy and Sell Stock.

Candidate: Sure. I’m given a prices array and I want to maximize profit from one buy-sell transaction — buy on some day, sell on a later day. If no profit exists, return zero. Can I confirm: exactly one transaction, and we return zero if prices only decrease?

Interviewer: Correct on both.

Candidate: Great. Brute force is O(n²): check every pair. To optimize, I’ll scan once and track the minimum price seen so far. At each step I compute the profit if I sold today, and I keep a running maximum. That’s O(n) time, O(1) space.

Interviewer: What if the prices array is empty?

Candidate: Good edge case. With float('inf') as my initial minimum and 0 as my initial profit, an empty loop returns 0, which is the correct answer since no transaction can happen. I’d also consider adding a guard clause like if not prices: return 0 at the top to make the intent explicit.

Interviewer: How would you change this if you could make unlimited transactions?

Candidate: That’s LeetCode 122. Instead of tracking a global minimum, you just sum up every upward price movement — add prices[i] - prices[i-1] whenever it’s positive. Essentially you’re capturing every profitable day-over-day gain.


Once you’re solid on the single-transaction version, these problems build on the same greedy and state-tracking patterns:

Interviewers frequently use Problem #121 as a warm-up and then pivot to #122 or #309 to test depth. Being ready for that pivot is itself a differentiator.


Practice This in a Mock Interview

Reading through this walkthrough will help you internalize the approach, but a real interview adds pressure that changes everything. You’re typing while narrating, responding to follow-ups you didn’t anticipate, and managing the clock. The only way to get comfortable is deliberate practice under realistic conditions.

The gap between “I understand this problem” and “I can execute it cleanly under pressure” is wider than most candidates expect.

Start a mock interview for Best Time to Buy and Sell Stock on Intervu and practice with a realistic AI interviewer that gives instant feedback on your approach.

Further reading:

Practice Like It's the Real Interview

Get instant feedback on your approach, communication, and code — powered by AI.

Start a Mock Interview →