cswork / libraryOpen practice workspace

Coding questions · Retool

Compute max profit with forced trades

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.

Given an array prices where prices[i] is the stock price on day i, solve two related tasks under a forced-trade constraint: (a) Exactly one transaction: choose one buy day and one later sell day to maximize profit; if prices never rise, return the least possible loss that results from exactly one buy and one sell. (b) Exactly two transactions: choose two non-overlapping buy-sell pairs (sell before the next buy) to maximize total profit; if necessary, include losses so that exactly two transactions are performed. Implement two functions (e.g., profitExactlyOne(prices), profitExactlyTwo(prices)) and specify assumptions (single share per transaction; no transaction costs; cannot short). Handle edge cases (empty or single-element arrays). No explicit time-complexity requirement.

What a Strong Answer Covers

  • A clear algorithm with the right data structures and enough pseudocode or code-level detail to implement it.
  • A correctness argument that explains why the algorithm covers all required cases.
  • Time and space complexity, plus at least one alternative approach when relevant.
  • Focused tests for normal cases, edge cases, and failure modes.

Follow-up Questions

  • How would the approach change if the input were streaming or too large for memory?
  • What invariants would you assert in production code?
  • Which tests would catch off-by-one, duplicate, or tie-breaking bugs?

Max Profit with Exactly One Forced Transaction

Given an array prices where prices[i] is the stock price on day i, you must perform exactly one buy-sell transaction: choose one buy day and one strictly later sell day to maximize profit.

The transaction is forced — you must buy once and sell once even if every choice loses money. If prices never rise, return the least-possible loss (the maximum of prices[j] - prices[i] over all i < j, which will be negative or zero).

Assumptions: single share per transaction, no transaction costs, you cannot short (sell must come after buy).

Edge cases: if the array has fewer than 2 elements no transaction is possible, so return 0.

Implement profitExactlyOne(prices).

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

Example 1

Input: ([7, 1, 5, 3, 6, 4],)
Output: 5

Explanation: Buy at 1 (day 1), sell at 6 (day 4): profit 5.

Example 2

Input: ([7, 6, 4, 3, 1],)
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).

Hints

  1. Track the minimum price seen so far while scanning left to right.
  2. At each day, the best sell-here profit is prices[i] - min_price_so_far; keep the running maximum.
  3. 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

Given an array prices where prices[i] is the stock price on day i, you must perform exactly two non-overlapping buy-sell transactions to maximize total profit. The two transactions must satisfy buy1 < sell1 < buy2 < sell2 in day order (you must sell the first share strictly before buying the second).

Both transactions are forced — even if a transaction must lose money, you must complete exactly two of them. The result may be negative.

Assumptions: single share per transaction, no transaction costs, you cannot short, and you cannot hold two shares at once.

Edge cases: two non-overlapping transactions require at least 4 days (4 distinct ordered days). If len(prices) < 4, two forced transactions are impossible, so return 0.

Implement profitExactlyTwo(prices).

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

Example 1

Input: ([3, 3, 5, 0, 0, 3, 1, 4],)
Output: 6

Explanation: Buy 3 (day1) sell 5 (day2) = +2, then buy 0 (day4) sell 4 (day8) = +4; total 6.

Example 2

Input: ([1, 2, 3, 4, 5],)
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).

Hints

  1. Use four chained DP states: hold1 (bought once), done1 (sold once), hold2 (bought a second time), done2 (sold twice).
  2. Transitions: hold1=max(hold1,-p); done1=max(done1,hold1+p); hold2=max(hold2,done1-p); done2=max(done2,hold2+p).
  3. 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.
  4. Two non-overlapping transactions need 4 ordered days, so short arrays (n < 4) are infeasible -> return 0.

Solution

Solution Alignment

The prompt asks for an implementation-level answer. The safest way to present it is to define the state, maintain clear invariants, then walk through complexity and tests.

Problem Restatement

Given an array prices where prices[i] is the stock price on day i, solve two related tasks under a forced-trade constraint: (a) Exactly one transaction: choose one buy day and one later sell day to maximize profit; if prices never rise, return the least possible loss that results from exactly one buy and one sell. (b) Exactly two transactions: choose two non-overlapping buy-sell pairs (sell before the next buy) to maximize total profit; if necessary, include losses so that exactly two transactions are performed. Implement two functions (e.g., profitExactlyOne(prices), profitExactlyTwo(prices)) and specify assumptions (single share per transaction; no transaction costs; cannot short). Handle ...

Recommended Approach

Start with a brute-force baseline to confirm correctness, then identify the repeated work or ordering property that enables a better data structure such as a hash map, heap, stack, queue, two pointers, prefix sums, BFS/DFS, or dynamic programming. Write the implementation around a small invariant and test that invariant directly.

Correctness

The implementation should maintain an invariant after each loop or operation that directly matches the problem statement. At termination, that invariant implies the returned value has considered every valid candidate exactly once, or has preserved the required data-structure state after every API call.

Complexity

State the baseline complexity and the optimized complexity. For most interview constraints, justify why the optimized approach meets the expected input size.

Edge Cases and Tests

Empty and singleton inputs, duplicates, ties, invalid inputs, boundary values, and tests that exercise the main invariant.