Compute drawdown, profit, and coin change
Company: Squarepoint Capital
Role: Data Scientist
Category: Coding & Algorithms
Difficulty: Medium
Interview Round: Technical Screen
Quick Answer: This question evaluates a candidate's ability to compute financial time-series metrics and apply algorithmic techniques such as array processing and optimization/dynamic programming to identify maximum drawdown and its indices.
Maximum Drawdown of a Cumulative PnL Series
Constraints
- 0 <= len(pnl) <= 10^5
- Each PnL value fits in a 32-bit signed integer.
- max_drawdown is always non-positive; it is 0 only when there is no decline.
Examples
Input: ([1, 3, 2, 5, 4, 0, 6],)
Expected Output: (-5, 3, 5)
Explanation: Peak 5 at index 3 falls to trough 0 at index 5: drawdown 0 - 5 = -5.
Input: ([10, 9, 8, 7],)
Expected Output: (-3, 0, 3)
Explanation: Strictly declining: peak 10 at index 0 falls to 7 at index 3, drawdown -3.
Input: ([1, 2, 3, 4, 5],)
Expected Output: (0, -1, -1)
Explanation: Non-decreasing series never drops below a prior peak, so there is no drawdown.
Input: ([5],)
Expected Output: (0, -1, -1)
Explanation: A single element cannot decline.
Input: ([],)
Expected Output: (0, -1, -1)
Explanation: Empty series has no drawdown.
Input: ([3, 1, 4, 1, 5, 9, 2, 6],)
Expected Output: (-7, 5, 6)
Explanation: The highest peak 9 at index 5 falls to 2 at index 6, a drawdown of -7, which is worse than the earlier 3->1 dips.
Input: ([-1, -2, -3, -2, -5],)
Expected Output: (-4, 0, 4)
Explanation: Peak -1 at index 0 falls to trough -5 at index 4: drawdown -5 - (-1) = -4.
Hints
- Sweep left to right while tracking the highest value (and its index) seen so far — the running peak.
- At each index, the candidate drawdown is current_value - running_peak. The minimum (most negative) such value over the whole sweep is the maximum drawdown.
- When you update the maximum drawdown, record the current peak's index as the start and the current index as the end.
Best Time to Buy and Sell Stock (LeetCode 121)
Constraints
- 0 <= len(prices) <= 10^5
- 0 <= prices[i] <= 10^4
- You must buy before you sell (no short-selling).
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: 0
Explanation: Prices only decline, so no profitable transaction; profit 0.
Input: ([1, 2, 3, 4, 5],)
Expected Output: 4
Explanation: Buy at 1, sell at 5: profit 4.
Input: ([2],)
Expected Output: 0
Explanation: Only one day; cannot buy and sell on different days.
Input: ([],)
Expected Output: 0
Explanation: No prices means no transaction is possible.
Input: ([3, 3, 3],)
Expected Output: 0
Explanation: Flat prices yield no profit.
Input: ([2, 4, 1],)
Expected Output: 2
Explanation: Buy at 2, sell at 4 for profit 2; the later dip to 1 is too late to sell against.
Hints
- Track the lowest price seen so far as you scan left to right.
- At each day, the best profit ending today is current_price - lowest_price_so_far. Keep the maximum of these.
- If prices only ever fall, no profitable transaction exists, so the answer stays 0.
Coin Change (LeetCode 322)
Constraints
- 1 <= len(coins) <= 12
- 1 <= coins[i] <= 2^31 - 1
- 0 <= amount <= 10^4
Examples
Input: ([1, 2, 5], 11)
Expected Output: 3
Explanation: 11 = 5 + 5 + 1, using 3 coins.
Input: ([2], 3)
Expected Output: -1
Explanation: Only coin 2 cannot sum to an odd amount 3.
Input: ([1], 0)
Expected Output: 0
Explanation: Amount 0 needs zero coins.
Input: ([1], 2)
Expected Output: 2
Explanation: 2 = 1 + 1.
Input: ([2, 5, 10, 1], 27)
Expected Output: 4
Explanation: 27 = 10 + 10 + 5 + 2, using 4 coins.
Input: ([186, 419, 83, 408], 6249)
Expected Output: 20
Explanation: Larger DP case; the minimum coin count to reach 6249 is 20.
Input: ([5], 0)
Expected Output: 0
Explanation: Amount 0 is reachable with zero coins regardless of denominations.
Input: ([3, 7], 5)
Expected Output: -1
Explanation: No combination of 3s and 7s sums to 5.
Hints
- Define dp[x] = the minimum number of coins needed to make amount x. dp[0] = 0.
- For each amount x from 1 to amount, try every coin c <= x: dp[x] = min(dp[x], dp[x - c] + 1).
- Initialize unreachable amounts to a sentinel larger than any valid answer (e.g. amount + 1). If dp[amount] is still the sentinel at the end, return -1.