Quick Overview

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.

Compute drawdown, profit, and coin change

Company: Squarepoint Capital

Role: Data Scientist

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

##### Question What is the maximum drawdown of a cumulative PnL (profit and loss) series, and when did it occur? Implement a function mdd(pnl) that returns the maximum drawdown (negative value) and its start and end indices. LeetCode 121. Best Time to Buy and Sell Stock LeetCode 322. Coin Change https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/ https://leetcode.com/problems/coin-change/description/

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

Given an array `pnl` representing a cumulative profit-and-loss (PnL) series over time, compute the maximum drawdown and the indices where it occurs. The maximum drawdown is the largest peak-to-trough decline in the series, measured as the most negative difference between a value and the highest value seen at or before it. It is a key risk metric in trading: it answers "what is the worst loss an investor would have experienced by buying at a peak and holding to a subsequent trough?" Implement a function `mdd(pnl)` that returns a tuple `(max_drawdown, start_index, end_index)` where: - `max_drawdown` is the maximum drawdown as a non-positive value (the trough value minus the preceding peak value). - `start_index` is the index of the peak that precedes the worst drawdown. - `end_index` is the index of the trough. If the series is non-decreasing (never drops below a prior peak) or is empty/has a single element, there is no drawdown: return `(0, -1, -1)`. Example: for `pnl = [1, 3, 2, 5, 4, 0, 6]`, the worst decline is from the peak `5` at index 3 down to `0` at index 5, a drawdown of `0 - 5 = -5`, so the answer is `(-5, 3, 5)`.

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.

Hints

  1. Sweep left to right while tracking the highest value (and its index) seen so far — the running peak.
  2. 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.
  3. 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)

You are given an array `prices` where `prices[i]` is the price of a given stock on day `i`. You want to maximize your profit by choosing a single day to buy one stock and choosing a different day in the future to sell that stock. Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return `0`. Example: for `prices = [7, 1, 5, 3, 6, 4]`, buy on day 1 (price 1) and sell on day 4 (price 6) for a profit of `6 - 1 = 5`. You must buy before you sell, so the answer is `5`.

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.

Hints

  1. Track the lowest price seen so far as you scan left to right.
  2. At each day, the best profit ending today is current_price - lowest_price_so_far. Keep the maximum of these.
  3. If prices only ever fall, no profitable transaction exists, so the answer stays 0.

Coin Change (LeetCode 322)

You are given an integer array `coins` representing coins of different denominations and an integer `amount` representing a total amount of money. Return the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return `-1`. You may assume that you have an infinite number of each kind of coin. Example: for `coins = [1, 2, 5]` and `amount = 11`, the answer is `3` because `11 = 5 + 5 + 1`.

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.

Hints

  1. Define dp[x] = the minimum number of coins needed to make amount x. dp[0] = 0.
  2. For each amount x from 1 to amount, try every coin c <= x: dp[x] = min(dp[x], dp[x - c] + 1).
  3. 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.

Loading coding console...