InterviewPrepKit

Home / Coding / 1-D Dynamic Programming

Best Time to Buy and Sell Stock with Transaction Fee

medium Original ↗
Solving tips
  • Model each day as a two-state machine: hold (own a share) vs cash (own nothing), tracking the best profit for each.
  • Transitions: hold = max(hold, cash - price); cash = max(cash, hold + price - fee). Charge the fee on exactly one side (the sell), never both.
  • Seed hold = -prices[0], cash = 0, and return the final cash; ending while still holding is never optimal.
  • Target O(n) time, O(1) space with two rolling scalars; seeding hold to 0 would grant a free first share.

Problem

You are given prices, where prices[i] is the price of a stock on day i, and an integer fee. You may complete as many transactions as you like (buy then sell), but:

  • you can hold at most one share at a time (you must sell before buying again), and
  • each completed transaction charges fee (count it once per buy-sell round trip — e.g. on the sell).

Return the maximum profit achievable.

Examples

  • prices = [1, 3, 2, 8, 4, 9], fee = 28 — buy at 1, sell at 8 (profit 8-1-2 = 5); buy at 4, sell at 9 (profit 9-4-2 = 3); total 8.
  • prices = [1, 3, 7, 5, 10, 3], fee = 36 — buy at 1, sell at 10 (profit 10-1-3 = 6); a single big transaction beats splitting once the fee is charged twice.
  • prices = [1, 2, 3], fee = 50 — no round trip clears the fee, so do nothing.

Constraints

  • 1 <= prices.length <= 5 * 10^4
  • 1 <= prices[i] < 5 * 10^4
  • 0 <= fee < 5 * 10^4

With n up to 5·10^4, an O(n) sweep is expected; anything exponential in the number of transactions is hopeless.

Think about it first

Hint 1 On each day you are in one of exactly two situations: you currently *hold* a share, or you are *cash* (hold nothing). Track the best profit for each situation as you move day to day.
Hint 2 Moving to day `i`: your best "holding" profit is either yesterday's holding, or you buy today from yesterday's cash (`cash - price`). Your best "cash" profit is either yesterday's cash, or you sell today from yesterday's holding (`hold + price - fee`).
Hint 3 Initialize `hold = -prices[0]` (bought day 0) and `cash = 0`. Sweep once, updating both. The answer is the final `cash` — you never want to end still holding a share. O(n) time, O(1) space.
Your workspace Not runnable by design — this is your interview scratchpad. Saved on this device.