The Trade Signal
An easy Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.
- Domain
- Python
- Difficulty
- easy
- Seniority
- L4
- Asked in
- Amazon
Problem
An asset's daily closing prices, one per day in order, hide a best single trade: one buy and a later sell with the largest positive gain. Return that gain with the buy and sell day indexes, earliest buy and then earliest sell when gains tie.
Buy low, sell high. Identify the ideal moment.
Example 1
Input:
prices = [7,1,5,3,6,4]
Output:
[5,1,4]
Example 2
Input:
prices = [7,6,4,3,1]
Output:
[0,-1,-1]
Worked solution and explanation
What this really is
Strip the trading costume and this is 'the biggest jump up from the lowest point behind you,' with one twist that changes everything: you report WHERE the jump happened, not just how big it was. The well-known max-profit answer remembers only the lowest price so far and hands back a number. That number is right and the answer is still wrong, because the buy day is gone. The real test is whether you carry the low's price AND its day through one pass, and whether you replace your best window only on a strict improvement so the earliest tradeable pair survives a tie. Forget the day and you can quote the gain but not the trade. Use >= and you quietly report a later window than the one asked for.
Building it up
Step 1: Start from the no-trade signal
Begin with best = (0, -1, -1). That tuple is the no-trade answer, and because any real trade must beat a gain of 0, a flat or falling series never replaces it. Break-even is handled without a special branch.
Step 2: Keep the low and its day together
Walk with enumerate(prices) so each price arrives with its day. When the price is the first one or strictly below low_price, it becomes the new low along with low_day, and there is nothing to sell on that same day, so move on.
Step 3: Commit a window only on strict improvement
Otherwise price - low_price is today's best possible gain. Only when it strictly beats best[0] does the window become (gain, low_day, day). An equal gain found later is a later trade, so it loses.
def best_trade(prices: list[int]) -> list[int]:
best = (0, -1, -1)
low_price = None
low_day = -1
for day, price in enumerate(prices):
if low_price is None or price < low_price:
low_price = price
low_day = day
continue
gain = price - low_price
if gain > best[0]:
best = (gain, low_day, day)
gain, buy_day, sell_day = best
return [gain, buy_day, sell_day]- Gain-only shortcut
- Tracks
min(low, price)andmax(best, price - low). Gets 5 on the first example and has no idea the buy was day 1. - Gain with its days
- Moves
low_daywithlow_priceand stores the whole window as one tuple, so the gain, buy day and sell day can never drift apart.
Common follow-up questions
- What if you could make as many buy and sell trades as you like? (Tests whether you see that summing every positive day-to-day rise is optimal.)
- What if you had to wait a day after each sell before buying again? (Tests tracking held, resting and free states day by day.)
- What if you could short-sell, profiting when the price falls? (Tests mirroring the logic with the highest price behind you.)