Quick Overview

A token walks a row of up to 50 signed cells, alternating right and left moves, and each move adds the sum of the cells it covers while the score must never drop below zero. Find the best score within up to 400 million moves, testing state design, the non-negative score constraint, and speed when the move count is huge.

Max Score of an Alternating Left-Right Walk Over a Row of Signed Cells

Company: Imbue

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: hard

Interview Round: HR Screen

A row of `n` cells holds integer values, some of which may be negative. A token starts on the leftmost cell with a score of `0`. You make at most `k` moves. The first move goes to the right, the second to the left, the third to the right, and so on, alternating. A move may cover any number of cells in its direction, including zero. Each move adds to the score the sum of the values of every cell from the move's starting cell to its ending cell, both included. The score must never be negative: a move that would leave the score below `0` is not allowed. Return the highest score you can have after at most `k` moves. ### Function Signature ```python def max_row_walk_score(board: list[int], k: int) -> int: ``` ### Rules - Cells are indexed `0` to `n - 1` from left to right, and the token starts on cell `0`. - Move number `t`, counting from `1`, is a right move when `t` is odd and a left move when `t` is even. A right move from cell `p` ends on any cell `q` with `p <= q <= n - 1`; a left move from cell `p` ends on any cell `q` with `0 <= q <= p`. - A move from `p` to `q` adds `board[min(p, q)] + ... + board[max(p, q)]` to the score. A move that ends where it starts (`q = p`) therefore adds `board[p]`. - After every move the score must be at least `0`. The check is made once per move, on the score after the whole move, not cell by cell during it. - The direction of each move is fixed by its number: to move right again after a right move, you first have to make a left move, which may be a zero-length move if the score allows it. - You may stop after any number of moves from `0` to `k`. Making no moves leaves the score at `0`, so the answer is never negative. ### Constraints - `1 <= len(board) <= 50` - `-4 * 10^5 <= board[i] <= 4 * 10^5` - `1 <= k <= 4 * 10^8` - The answer can exceed `2^31 - 1` (it can reach `8 * 10^15`); use 64-bit integers in typed languages. - The original take-home allowed cell values up to `4 * 10^8` in absolute value, which pushes the best score toward `8 * 10^18` and makes 64-bit overflow a real concern. This version caps `|board[i]|` at `4 * 10^5` so every answer stays below `2^53`; `k` keeps its original bound. ### Examples **Example 1** ```text Input: board = [-2, 5, -1, 3], k = 3 Output: 19 ``` Move 1 goes right from cell `0` to cell `3` and adds `-2 + 5 - 1 + 3 = 5`. Move 2 goes left from cell `3` to cell `1` and adds `5 - 1 + 3 = 7`, for a score of `12`. Move 3 goes right from cell `1` to cell `3` and adds `7` again, for `19`. **Example 2** ```text Input: board = [1, -8, 6], k = 1000000 Output: 5999983 ``` A first move to cell `2` would add `1 - 8 + 6 = -1` to a score of `0`, which is not allowed, and a move to cell `1` would add `-7`. So moves 1 and 2 stay on cell `0` and add `1` each. With a score of `2`, move 3 goes right to cell `2` and adds `-1`, leaving `1`. Every later move stays on cell `2` and adds `6`, giving `1 + 6 * 999997 = 5999983`. **Example 3** ```text Input: board = [-5, 4], k = 10 Output: 0 ``` The first move starts on cell `0` and adds either `-5` (staying) or `-5 + 4 = -1` (moving to cell `1`). Both would make the score negative, so no move can be made and the score stays `0`.

Overview: A token walks a row of up to 50 signed cells, alternating right and left moves, and each move adds the sum of the cells it covers while the score must never drop below zero. Find the best score within up to 400 million moves, testing state design, the non-negative score constraint, and speed when the move count is huge.

Read the full Imbue Software Engineer interview experience this question came from

A row of `n` cells holds integer values `board[0..n-1]`, some of which may be negative. A token starts on the leftmost cell (cell `0`) with a score of `0`. You make at most `k` moves. Move number `t`, counting from `1`, is a right move when `t` is odd and a left move when `t` is even, so the first move goes right and the directions alternate. - A right move from cell `p` ends on any cell `q` with `p <= q <= n - 1`; a left move from cell `p` ends on any cell `q` with `0 <= q <= p`. A move may cover any number of cells in its direction, including zero (`q = p`). - A move from `p` to `q` adds `board[min(p, q)] + ... + board[max(p, q)]` to the score, both endpoints included. A move that ends where it starts therefore adds `board[p]`. - After every move the score must be at least `0`. The check is made once per move, on the score after the whole move, not cell by cell during it. A move that would leave the score below `0` is not allowed. - The direction of each move is fixed by its number: to move right again after a right move, you first have to make a left move, which may be a zero-length move if the score allows it. - You may stop after any number of moves from `0` to `k`. Making no moves leaves the score at `0`, so the answer is never negative. Return the highest score you can have after at most `k` moves. The answer can exceed `2^31 - 1` (it can reach `8 * 10^15`, which is still below `2^53`), so it must be computed and returned as a 64-bit integer: `long` in Java, `long long` in C++. ### Example 1 ```text Input: board = [-2, 5, -1, 3], k = 3 Output: 19 ``` Move 1 goes right from cell `0` to cell `3` and adds `-2 + 5 - 1 + 3 = 5`. Move 2 goes left from cell `3` to cell `1` and adds `5 - 1 + 3 = 7`, for a score of `12`. Move 3 goes right from cell `1` to cell `3` and adds `7` again, for `19`. ### Example 2 ```text Input: board = [1, -8, 6], k = 1000000 Output: 5999983 ``` A first move to cell `2` would add `1 - 8 + 6 = -1` to a score of `0`, which is not allowed, and a move to cell `1` would add `-7`. So moves 1 and 2 stay on cell `0` and add `1` each. With a score of `2`, move 3 goes right to cell `2` and adds `-1`, leaving `1`. Every later move stays on cell `2` and adds `6`, giving `1 + 6 * 999997 = 5999983`. ### Constraints - `1 <= len(board) <= 50` - `-4 * 10^5 <= board[i] <= 4 * 10^5` - `1 <= k <= 4 * 10^8` - The answer can exceed `2^31 - 1` (up to `8 * 10^15`); use 64-bit integers in typed languages.

Constraints

  • 1 <= len(board) <= 50
  • -4 * 10^5 <= board[i] <= 4 * 10^5
  • 1 <= k <= 4 * 10^8
  • The answer can exceed 2^31 - 1 (it can reach 8 * 10^15, below 2^53); use long in Java and long long in C++.

Examples

Input: ([7], 1)

Expected Output: 7

Explanation: Minimum: single cell, one move; the zero-length right move adds 7.

Input: ([-3], 5)

Expected Output: 0

Explanation: Single negative cell: every move would add -3, so no move is legal and the score stays 0.

Hints

  1. For a fixed number of moves and a fixed cell, a higher score is never worse: any move that is legal from the lower score is also legal from the higher one.
  2. A right move from x to y and the left move back from y to x add the same segment sum, so a profitable segment can be repeated move after move.
  3. k can be 4 * 10^8, far too many moves to simulate one at a time. Think about how the best scores change over long stretches of moves.

Loading coding console...

Show the approach

Approach

Reformulation: before a right move the token sits on some cell x and the move ends on y >= x, adding pre[y+1] - pre[x] (pre is the prefix-sum array); a left move from y to x <= y adds the same expression. Dominance: for a fixed number of moves and a fixed cell, a higher score is never worse, because every later move that keeps a lower score non-negative also keeps the higher score non-negative and ends higher. So it is enough to keep, for each cell, the best score after each move (-1 marks an unreachable cell). One right move is a[y] = pre[y+1] + max over x <= y of (b[x] - pre[x]); one left move is b[x] = -pre[x] + max over y >= x of (a[y] + pre[y+1]); both take O(n) with a running maximum, and any result below 0 is discarded because that move is illegal. Because k can be 410^8, the simulation jumps over long stretches. When three consecutive post-left-move vectors b_j, b_{j+1}, b_{j+2} and the right-move vectors a_j, a_{j+1} have the same reachable cells and constant per-cell differences D and E, the code tests whether the extrapolations b_j + mD and a_j + mE stay consistent with one round of the two moves. For a linear input, each output cell is a maximum of linear functions of m and therefore convex, and it agrees with the extrapolated line at m = 0 and m = 1. So the set of m where the extrapolation is exact, including the clamp to illegal moves, is an interval starting at 1. Exponential search followed by binary search finds the end of that interval, and the simulation jumps there. Every per-cell value is linear across a jump, so the best score over the skipped moves is reached at one of its ends. The answer is the largest score seen over all move counts up to k, or 0 if no first move is legal. Edge cases: a single cell; no legal first move (every prefix sum negative); odd k, where the last move is a right move; and scores up to 810^15, kept in 64-bit integers (exact in JavaScript because they stay below 2^53).

Time complexity:
O(n * (R + J * log k)), where R is the number of rounds simulated directly and J the number of linear jumps
Space complexity:
O(n)