Zigzag diagonal walk through a matrix from a chosen left-column start
Company: Quora
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: easy
Interview Round: Technical Screen
Walk through a matrix along its diagonals in a zigzag. The walk only ever moves in two directions, up-right and down-left; when the next step would leave the matrix, it bounces onto the neighboring diagonal and reverses direction. The walk may start at the top-left cell or at any other cell of the leftmost column. Return the values in the order the walk visits them.
The report gives only the movement rule and the possible starting cells; this version fixes the remaining details in the Rules below.
### Function Signature
```python
def diagonal_bounce(matrix: list[list[int]], start_row: int) -> list[int]:
```
### Rules
- Rows are numbered from `0` at the top to `m - 1`, and columns from `0` on the left to `n - 1`. The walk starts at cell `(start_row, 0)`, moving up-right.
- Moving up-right from `(r, c)`: if `(r - 1, c + 1)` is inside the matrix, step there. Otherwise bounce: if `c == n - 1`, step down to `(r + 1, c)`; else step right to `(r, c + 1)`. After a bounce the direction is down-left.
- Moving down-left from `(r, c)`: if `(r + 1, c - 1)` is inside the matrix, step there. Otherwise bounce: if `r == m - 1`, step right to `(r, c + 1)`; else step down to `(r + 1, c)`. After a bounce the direction is up-right.
- The walk ends at the bottom-right cell `(m - 1, n - 1)`, which it always reaches. Report every visited cell once, in visit order, including the start and the end.
- When `start_row > 0`, the cells `(r, c)` with `r + c < start_row` are never visited.
### Constraints
- `m = len(matrix)`, `n = len(matrix[0])`, every row has length `n`, and `1 <= m * n <= 10^5`
- `0 <= start_row < m`
- `-10^9 <= matrix[r][c] <= 10^9`
### Examples
**Example 1**
```text
Input: matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], start_row = 0
Output: [1, 2, 4, 7, 5, 3, 6, 8, 9]
```
From 1, the up-right step would leave the top edge, so the walk bounces right to 2 and turns down-left to 4. At the left edge it bounces down to 7 and goes up-right through 5 to 3. At the right edge it bounces down to 6, goes down-left to 8, and at the bottom edge bounces right to 9, the bottom-right cell.
**Example 2**
```text
Input: matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], start_row = 1
Output: [4, 2, 3, 5, 7, 8, 6, 9]
```
From 4 the walk goes up-right to 2, bounces right to 3 at the top edge, goes down-left through 5 to 7, bounces right to 8 at the bottom edge, goes up-right to 6, and bounces down to 9 at the right edge. The cell holding 1 is never visited.
**Example 3**
```text
Input: matrix = [[1, 2, 3, 4], [5, 6, 7, 8]], start_row = 1
Output: [5, 2, 3, 6, 7, 4, 8]
```
5 up-right to 2; bounce right to 3; down-left to 6; bounce right to 7 at the bottom edge; up-right to 4; bounce down to 8 at the right edge.
Overview: Walk through a matrix along its anti-diagonals in a zigzag, moving only up-right or down-left and bouncing onto the next diagonal at each edge, starting from the top-left cell or any cell of the left column. Return the values in visit order. The problem tests boundary handling and careful grid simulation.
Read the full Quora Software Engineer interview experience this question came from
A matrix with `m` rows and `n` columns is walked along its diagonals in a zigzag. Rows are numbered from `0` at the top to `m - 1` at the bottom, and columns from `0` on the left to `n - 1` on the right. The walk only ever moves in two directions, up-right and down-left; when the next step would leave the matrix, it bounces onto the neighboring diagonal and reverses direction. The walk may start at the top-left cell or at any other cell of the leftmost column.
Implement `diagonal_bounce(matrix, start_row)` and return the values of the visited cells in the order the walk visits them.
### Rules
- The walk starts at cell `(start_row, 0)`, moving up-right.
- Moving up-right from `(r, c)`: if `(r - 1, c + 1)` is inside the matrix, step there. Otherwise bounce: if `c == n - 1`, step down to `(r + 1, c)`; else step right to `(r, c + 1)`. After a bounce the direction is down-left.
- Moving down-left from `(r, c)`: if `(r + 1, c - 1)` is inside the matrix, step there. Otherwise bounce: if `r == m - 1`, step right to `(r, c + 1)`; else step down to `(r + 1, c)`. After a bounce the direction is up-right.
- The walk ends at the bottom-right cell `(m - 1, n - 1)`, which it always reaches. Report every visited cell once, in visit order, including the start and the end (when the start cell is `(m - 1, n - 1)` itself, the result holds just that one value).
- When `start_row > 0`, the cells `(r, c)` with `r + c < start_row` are never visited.
- Values are returned unchanged. Every value fits in a signed 32-bit integer (none can exceed 2^31 - 1), so the Java and C++ signatures use `int`.
### Example 1
```text
Input: matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], start_row = 0
Output: [1, 2, 4, 7, 5, 3, 6, 8, 9]
```
From 1, the up-right step would leave the top edge, so the walk bounces right to 2 and turns down-left to 4. At the left edge it bounces down to 7 and goes up-right through 5 to 3. At the right edge it bounces down to 6, goes down-left to 8, and at the bottom edge bounces right to 9, the bottom-right cell.
### Example 2
```text
Input: matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], start_row = 1
Output: [4, 2, 3, 5, 7, 8, 6, 9]
```
From 4 the walk goes up-right to 2, bounces right to 3 at the top edge, goes down-left through 5 to 7, bounces right to 8 at the bottom edge, goes up-right to 6, and bounces down to 9 at the right edge. The cell holding 1 is never visited.
### Constraints
- `m = len(matrix)`, `n = len(matrix[0])`, every row has length `n`, and `1 <= m * n <= 10^5`
- `0 <= start_row < m`
- `-10^9 <= matrix[r][c] <= 10^9`
Constraints
- m = len(matrix), n = len(matrix[0]), every row has length n, and 1 <= m * n <= 10^5
- 0 <= start_row < m
- -10^9 <= matrix[r][c] <= 10^9 (every value fits in a signed 32-bit integer)
Examples
Input: ([[1, 2, 3], [4, 5, 6], [7, 8, 9]], 0)
Expected Output: [1, 2, 4, 7, 5, 3, 6, 8, 9]
Explanation: Example 1: square start at row 0; the up-right move at the top-right corner (0, 2) must bounce down, not right.
Input: ([[1, 2, 3], [4, 5, 6], [7, 8, 9]], 1)
Expected Output: [4, 2, 3, 5, 7, 8, 6, 9]
Explanation: Example 2: square middle-row start skips (0, 0); the down-left move reaching the bottom-left corner (2, 0) must bounce right, not down; the first diagonal runs up-right even though start_row is odd.
Hints
- Trace Example 2 by hand, tracking both the current cell and the current direction, and note why the cell holding 1 never appears.
- At a corner both bounce conditions look plausible: apply them in exactly the order the rules state for the current direction.
- The walk stops only at the bottom-right cell, so check a 1x1 matrix, a single row and a single column against the rules before generalizing.