InterviewPrepKit

Home / Coding / 1-D Dynamic Programming

Best Time to Buy and Sell Stock IV

hard Original ↗
Solving tips
  • This is Stock III generalized: state is (day, transactions left, holding), transition is max(rest, act) with the transaction charged on the buy.
  • Add the k >= n//2 shortcut up front; a transaction needs two days, so beyond that cap it degenerates to unlimited trading (greedy sum of positive daily diffs).
  • Space-optimize to buy[t]/sell[t] rolling arrays; the t-th buy is funded by sell[t-1], the previous completed transaction, not the current one.
  • Target O(n*k) time, O(k) space; seed buy[] to negative infinity and handle empty prices or k==0 before allocating.

Problem

You are given an integer k and an array prices, where prices[i] is the price of a stock on day i. You may complete at most k transactions to maximize your profit. A transaction is one buy followed by a later sell, and you may hold at most one share at a time (sell before buying again). You never have to trade. Return the maximum total profit achievable. This is the general form of Stock III, where k was fixed at 2.

Examples

  • k = 2, prices = [2, 4, 1]2 — buy at 2, sell at 4 for +2; the second transaction adds nothing.
  • k = 2, prices = [3, 2, 6, 5, 0, 3]7 — buy 2 sell 6 (+4), then buy 0 sell 3 (+3); total 7.
  • k = 3, prices = [1, 2, 3, 4, 5]4 — the whole rise is one clean transaction; extra allowed transactions go unused.

Constraints

  • 0 <= k <= 100
  • 0 <= len(prices) <= 1000
  • 0 <= prices[i] <= 1000
  • At most k non-overlapping transactions.
  • Note k can exceed len(prices) // 2. Beyond that cap, extra transactions are useless (each needs at least two days), so the problem degenerates into “unlimited transactions”.

Think about it first

Hint 1 This is Stock III with `k` instead of `2`. Carry the same state: how many transactions remain, and whether you currently hold a share. Each day you rest or act.
Hint 2 A single transaction spans at least two days (buy one day, sell a later day). So if `k >= len(prices) // 2`, you can never be limited by `k` — you may as well grab every upward move. That special case collapses to a simple greedy sum and avoids a huge `k`.
Hint 3 Otherwise run the DP over days and `t = 1..k`. Keep, for each `t`, the best "just bought the t-th share" balance and the best "just sold the t-th share" profit, updating both once per day. The answer is the best-sold value at `t = k`, which needs only O(k) rolling storage.
Your workspace Not runnable by design — this is your interview scratchpad. Saved on this device.