Integer to Roman: The Greedy Mapping That Always Shows Up in Interviews

Master the classic coding interview problem 'Best Time to Buy and Sell Stock' with step-by-step explanation โ from the naive brute force approach, recognizing patterns, to the optimal one-pass O(n) solution using sliding window / two-pointer technique. Complete with array visualization, complexity analysis, and the intuition behind every decision.

The secret behind many array problems: "What if I track the minimum so far while scanning?" โ this pattern shows up everywhere, from stock trading to rainwater trapping.
You are given an array prices where prices[i] is the price of a given stock on the i-th day. Find the maximum profit from a single transaction โ buy on one day, sell on a later day. If no profit is possible (prices only decrease), return 0.
Constraints:
1 <= prices.length <= 10โต0 <= prices[i] <= 10โดExamples from the prompt:
Input: prices = [7, 1, 5, 3, 6, 4]
Output: 5Buy on day 2 (price = 1), sell on day 5 (price = 6), profit = 6 - 1 = 5.
Input: prices = [7, 6, 4, 3, 1]
Output: 0No transaction yields profit โ prices only go down.
First thought: try every possible buy-sell pair.
func maxProfit(prices []int) int {
maxProfit := 0
n := len(prices)
for buy := 0; buy < n; buy++ {
for sell := buy + 1; sell < n; sell++ {
profit := prices[sell] - prices[buy]
if profit > maxProfit {
maxProfit = profit
}
}
}
return maxProfit
}Straightforward logic: for each buy day, try every sell day after it. Compute profit, track the maximum.
Complexity: O(nยฒ) โ full nested loop. For n = 10โต, this runs ~10ยนโฐ iterations. Won't pass.
Re-examine the example: [7, 1, 5, 3, 6, 4]
For any candidate sell day, maximum profit comes from buying at the lowest price seen before that day.
| Day | Price | Min price before today | Profit if sell today |
|---|---|---|---|
| 1 | 7 | N/A (can't sell yet) | - |
| 2 | 1 | 7 | 1 - 7 = -6 โ max(previous, 0) = 0 |
| 3 | 5 | 1 (updated after seeing 1) | 5 - 1 = 4 |
| 4 | 3 | 1 | 3 - 1 = 2 |
| 5 | 6 | 1 | 6 - 1 = 5 |
| 6 | 4 | 1 | 4 - 1 = 3 |
Maximum profit: max(0, 4, 2, 5, 3) = 5. Matches expected output.
From the table above, we realize: no nested loop needed. Just one pass left to right, maintaining two values:
min_price)max_profit)At each step i:
prices[i] - min_pricemax_profit if this profit is largermin_price if prices[i] is smaller than min_pricefunc maxProfit(prices []int) int {
minPrice := math.MaxInt32
maxProfit := 0
for _, price := range prices {
if price < minPrice {
minPrice = price
} else {
profit := price - minPrice
if profit > maxProfit {
maxProfit = profit
}
}
}
return maxProfit
}Or a more concise version:
func maxProfit(prices []int) int {
minPrice := math.MaxInt32
maxProfit := 0
for _, price := range prices {
minPrice = min(minPrice, price)
maxProfit = max(maxProfit, price-minPrice)
}
return maxProfit
}What about the no-profit case? If prices only decrease (example 2: [7, 6, 4, 3, 1]), then price - min_price is always negative. But max_profit starts at 0, and max(0, negative) = 0. So it returns 0 โ matching the requirement.
prices = [7, 1, 5, 3, 6, 4]
i=0: price=7 โ min_price=7 profit=N/A max_profit=0
i=1: price=1 โ min_price=1 profit=N/A max_profit=0
i=2: price=5 โ min_price=1 profit=4 max_profit=4 โ
i=3: price=3 โ min_price=1 profit=2 max_profit=4
i=4: price=6 โ min_price=1 profit=5 max_profit=5 โ (new max!)
i=5: price=4 โ min_price=1 profit=3 max_profit=5
Return 5| Aspect | Value |
|---|---|
| Time | O(n) โ single array traversal |
| Space | O(1) โ only two variables (min_price, max_profit) |
For n = 10โต, this solution completes in <1ms in any language.
The "track minimum from the left while scanning" pattern is a building block for many problem variants:
current_sum and max_sumAll stem from the same idea: maintain optimal state from data already passed, update state as you move forward.
Best profit comes from buying at the lowest price seen so far and selling at the current price. Track both in one pass.
This problem teaches that brute force can crumble with a single simple observation. Always ask before writing a nested loop: "What do I actually need to remember from the data I've already seen?"



