Compute max profit with forced trades
Company: Retool
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: Medium
Interview Round: Technical Screen
Quick Answer: Compute max profit with forced trades evaluates algorithm design, data structures, correctness, complexity, edge cases, and implementation details in a realistic interview setting. A strong answer states assumptions, handles edge cases, explains trade-offs, and shows how to validate the result clearly.
Max Profit with Exactly One Forced Transaction
Constraints
- 0 <= len(prices)
- Prices may be any integers (no non-negativity assumption needed for the algorithm)
- Exactly one buy and one strictly-later sell are forced
- If len(prices) < 2, return 0 (no valid transaction)
Examples
Input: ([7, 1, 5, 3, 6, 4],)
Expected Output: 5
Explanation: Buy at 1 (day 1), sell at 6 (day 4): profit 5.
Input: ([7, 6, 4, 3, 1],)
Expected Output: -1
Explanation: Prices only fall; the least loss from a forced buy-sell is -1 (e.g. buy 7 sell 6, or buy 4 sell 3).
Input: ([5],)
Expected Output: 0
Explanation: Single element: no valid buy-sell pair, return 0.
Input: ([],)
Expected Output: 0
Explanation: Empty array: no transaction possible, return 0.
Input: ([2, 4, 1],)
Expected Output: 2
Explanation: Buy at 2, sell at 4: profit 2.
Input: ([3, 3],)
Expected Output: 0
Explanation: Buy and sell at equal price: forced transaction yields 0.
Input: ([1, 2],)
Expected Output: 1
Explanation: Buy at 1, sell at 2: profit 1.
Hints
- Track the minimum price seen so far while scanning left to right.
- At each day, the best sell-here profit is prices[i] - min_price_so_far; keep the running maximum.
- Seed the answer with prices[1] - prices[0] so a forced loss is returned when prices only fall.
Max Profit with Exactly Two Forced Transactions
Constraints
- 0 <= len(prices)
- Exactly two non-overlapping transactions are forced: buy1 < sell1 < buy2 < sell2
- You cannot hold two shares simultaneously
- If len(prices) < 4, two forced transactions are impossible; return 0
Examples
Input: ([3, 3, 5, 0, 0, 3, 1, 4],)
Expected Output: 6
Explanation: Buy 3 (day1) sell 5 (day2) = +2, then buy 0 (day4) sell 4 (day8) = +4; total 6.
Input: ([1, 2, 3, 4, 5],)
Expected Output: 3
Explanation: With only 5 strictly-increasing days, the best two non-overlapping forced pairs sum to 3 (e.g. buy1 sell2 = +1, buy3 sell5 = +2).
Input: ([7, 6, 4, 3, 1],)
Expected Output: -2
Explanation: Prices only fall; the least-loss forced pair of two transactions totals -2.
Input: ([5],)
Expected Output: 0
Explanation: Fewer than 4 days: two forced transactions are impossible, return 0.
Input: ([],)
Expected Output: 0
Explanation: Empty array: return 0.
Input: ([1, 2, 4, 2, 5, 7, 2, 4, 9, 0],)
Expected Output: 13
Explanation: Buy 1 sell 7 = +6, then buy 2 sell 9 = +7; total 13.
Input: ([5, 4, 3, 2],)
Expected Output: -2
Explanation: Only ordering buy5 sell4 (-1) then buy3 sell2 (-1) = -2; the sole feasible forced pair.
Input: ([2, 1, 4, 3],)
Expected Output: -2
Explanation: Exactly 4 days, one feasible configuration: buy 2 sell 1 (-1) then buy 4 sell 3 (-1) = -2.
Hints
- Use four chained DP states: hold1 (bought once), done1 (sold once), hold2 (bought a second time), done2 (sold twice).
- Transitions: hold1=max(hold1,-p); done1=max(done1,hold1+p); hold2=max(hold2,done1-p); done2=max(done2,hold2+p).
- Initialize all states to -infinity so that done2 is only reachable through exactly two completed buy-sell pairs — this enforces 'exactly two' rather than 'at most two', and allows a negative (forced-loss) answer.
- Two non-overlapping transactions need 4 ordered days, so short arrays (n < 4) are infeasible -> return 0.