Quick 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.

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

  1. Trace Example 2 by hand, tracking both the current cell and the current direction, and note why the cell holding 1 never appears.
  2. At a corner both bounce conditions look plausible: apply them in exactly the order the rules state for the current direction.
  3. 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.

Loading coding console...

Show the approach

Approach

Simulate the walk exactly as the rules describe. Keep the current cell (r, c) and a direction flag, start at (start_row, 0) moving up-right, and record the start value. While the current cell is not (m - 1, n - 1): if the diagonal neighbour in the current direction is inside the matrix, move there; otherwise apply the bounce in the stated precedence (up-right: the right edge wins, so c == n - 1 steps down, else step right; down-left: the bottom edge wins, so r == m - 1 steps right, else step down) and flip the direction. Record each new cell's value.

Invariant: a diagonal step keeps r + c unchanged and a bounce raises it by exactly 1, landing on an end of the next anti-diagonal from which the new direction runs that whole diagonal. So the walk covers the anti-diagonals d = start_row, start_row + 1, ..., m + n - 2 in order, each completely and exactly once, alternating direction and beginning up-right on d = start_row, whose bottom-left end is (start_row, 0). Every bounce stays inside the matrix: an up-right bounce with c == n - 1 has r < m - 1, because (m - 1, n - 1) would already have ended the walk, and otherwise r == 0 with c + 1 < n; the down-left case is symmetric. The last anti-diagonal holds only (m - 1, n - 1), so the loop terminates there after visiting exactly the cells with r + c >= start_row, none twice.

Edge cases: a 1x1 matrix, or a single column started at row m - 1, returns one value; a single row is returned left to right; a single column is returned top to bottom from start_row.

Time complexity:
O(m * n)
Space complexity:
O(m * n)