Best Time to Buy and Sell Stock — Coding Interview Walkthrough
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.
| Skill | What Interviewers Observe |
|---|---|
| Constraint recognition | Do you catch “buy before sell” immediately? |
| Greedy intuition | Can you reason about local vs. global optima? |
| Optimization instinct | Do you move naturally from O(n²) to O(n)? |
| Edge case awareness | Do you handle all-decreasing prices and single-element arrays? |
| Communication clarity | Can you explain a simple algorithm without over-complicating it? |
| Follow-up readiness | Can 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
0for 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.
| Approach | Time Complexity | Space 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.
---
Step 4 — Optimal Strategy
- Initialize
min_priceto positive infinity (orprices[0]), since you haven’t seen any price yet. - Initialize
max_profitto0, since no transaction means no profit. - Iterate through each price in
prices. - If the current price is lower than
min_price, updatemin_price. - Otherwise, compute
current_profit = price - min_price. - If
current_profitexceedsmax_profit, updatemax_profit. - 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 initialmin_priceis more robust thanprices[0], since it handles edge cases like an empty array without an index error. - The variable names
min_priceandmax_profitcommunicate intent without needing comments. - The
elsebranch 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
| Operation | Complexity |
|---|---|
| Iterating through the array | O(n) |
| Each comparison/assignment | O(1) |
| Overall time | O(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 > iis the most common brute-force bug. Always verify that your buy day precedes your sell day. -
Initializing
min_priceto0. Zero seems like a safe default, but if all prices are positive (which they are for stocks), this would causemin_priceto never update. Usefloat('inf')orprices[0]. -
Returning a negative profit. If prices only decrease (e.g.,
[7, 6, 4, 3, 1]), the correct answer is0. You simply don’t trade. Forgetting to initializemax_profit = 0and 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 return0naturally, 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.
Related Problems to Practice
Once you’re solid on the single-transaction version, these problems build on the same greedy and state-tracking patterns:
- Best Time to Buy and Sell Stock II (LeetCode 122). Unlimited transactions; greedily capture every upward movement.
- Best Time to Buy and Sell Stock III (LeetCode 123). At most 2 transactions, introducing state machine / DP thinking.
- Best Time to Buy and Sell Stock IV (LeetCode 188). At most k transactions, the full DP generalization of the series.
- Best Time to Buy and Sell Stock with Cooldown (LeetCode 309). Adds a rest-day constraint and requires tracking state across days.
- Maximum Subarray (LeetCode 53). Kadane’s algorithm, a related greedy pattern on a transformed version of this problem.
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:
- How to Prepare for a Coding Interview in 2026, the complete roadmap and study plans
- Why LeetCode alone isn’t enough, and what to practice instead
- Practice any LeetCode problem as a live mock interview
- The Grind 75 Pathway, a structured study plan with AI practice links
- Browse all walkthroughs on GitHub, condensed solutions with code