121. Best Time to Buy and Sell Stock
easyAsked at AppleBest Time to Buy and Sell Stock is Apple's canonical single-pass max-tracking question. The trick is recognizing this as 'maximum running-difference' — you only need the minimum-so-far and the best diff. The O(n^2) brute force is mentioned and rejected; the linear scan is the answer.
By Sam K., Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in Apple loops.
- Glassdoor (2026-Q1)— Apple SWE phone-screen reports list this as the most-repeated array-scan easy.
- Blind (2025-12)— Apple new-grad reports cite Best Time to Buy and Sell Stock as the 10-minute warm-up.
Problem
You are given an array prices where prices[i] is the price of a given stock on the ith day. You want to maximize your profit by choosing a single day to buy one stock and choosing a different day in the future to sell that stock. Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return 0.
Constraints
1 <= prices.length <= 10^50 <= prices[i] <= 10^4
Examples
Example 1
prices = [7,1,5,3,6,4]5Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5. Note that buying on day 2 and selling on day 1 is not allowed because you must buy before you sell.
Example 2
prices = [7,6,4,3,1]0Explanation: In this case, no transactions are done and the max profit = 0.
Approaches
1. Brute-force (every pair)
For each buy day, scan all later days to find max profit.
- Time
- O(n^2)
- Space
- O(1)
function maxProfit(prices) {
let best = 0;
for (let i = 0; i < prices.length; i++) {
for (let j = i + 1; j < prices.length; j++) {
best = Math.max(best, prices[j] - prices[i]);
}
}
return best;
}Tradeoff: Quadratic; times out on the upper-bound constraints. Mention it and reject.
2. Single pass with running min (optimal)
Track minPrice seen so far and best profit. At each day, update best = max(best, price - minPrice), then update minPrice = min(minPrice, price).
- Time
- O(n)
- Space
- O(1)
function maxProfit(prices) {
let minPrice = Infinity;
let best = 0;
for (const p of prices) {
if (p < minPrice) minPrice = p;
else if (p - minPrice > best) best = p - minPrice;
}
return best;
}Tradeoff: Single linear pass, constant space. The else-if structure is correct because if p drops the minPrice, we can't make profit using THIS p as a sell — the next iteration's p might. Apple's preferred form.
Apple-specific tips
Apple grades the single-pass mental model: 'at every position, the best profit ending HERE is price - (the minimum seen so far).' Saying that sentence makes the linear scan inevitable. Then it's just 'track that running min as we go.' Bonus: mention that this generalizes to maximum subarray (Kadane's) if you treat the prices as a delta sequence.
Common mistakes
- Allowing prices[j] - prices[i] with j < i (selling before buying).
- Initializing best to -Infinity — the problem says return 0 when no profit, so 0 is the right initial value.
- Tracking maxPrice instead of minPrice — that solves a different (and trivial) problem.
Follow-up questions
An interviewer at Apple may pivot to one of these next:
- Best Time to Buy and Sell Stock II (LC 122) — unlimited transactions.
- Best Time to Buy and Sell Stock III (LC 123) — at most 2 transactions, DP.
- Best Time to Buy and Sell Stock with Cooldown (LC 309) — state-machine DP.
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
Why else-if and not two separate if statements?
If the price is a new minimum, you can't compute a profit using THIS price as the sell — there's no earlier minimum. The else-if cleanly captures that: update min OR check for new best, not both.
Does it matter where I start minPrice?
Setting it to Infinity (or prices[0]) is safe — the first iteration always sets it correctly. Setting it to 0 would silently allow nonsensical profits on the first day.
Free learning resources
Curated free links for this problem.