Zigzag Traverse
Zigzag Traverse
Category
Arrays
Difficulty
Hard
Problem Statement
Given a two-dimensional array (not necessarily square), traverse it in a zigzag (diagonal) order and return the elements as a one-dimensional list. The traversal starts at the top-left corner, moves diagonally down-left, then diagonally up-right, alternating direction with each diagonal, collecting all elements.
Intuition
The zigzag pattern alternates between moving diagonally down-left and diagonally up-right. At each boundary (top row, bottom row, left column, right column), we change direction. The trick is correctly handling the boundary transitions: when we hit a wall, we need to determine the next starting position for the opposite diagonal direction. The direction flips each time we reach a boundary.
Approach
- Start at position
(0, 0)and set the initial direction to "going down." - At each step, add the current element to the result.
- Determine the next position based on the current direction:
- Going down (down-left diagonal): move to
(row+1, col-1). - Going up (up-right diagonal): move to
(row-1, col+1).
- Going down (down-left diagonal): move to
- Handle boundary conditions to adjust position and flip direction:
- Going down and hit the bottom row: move right (
col+1), flip direction. - Going down and hit the left column: move down (
row+1), flip direction. - Going up and hit the right column: move down (
row+1), flip direction. - Going up and hit the top row: move right (
col+1), flip direction.
- Going down and hit the bottom row: move right (
- Continue until all elements are visited.
Pseudocode
function zigzagTraverse(array):
height = length(array) - 1
width = length(array[0]) - 1
result = []
row = 0
col = 0
goingDown = true
while row >= 0 and row <= height and col >= 0 and col <= width:
result.append(array[row][col])
if goingDown:
if col == 0 or row == height:
goingDown = false
if row == height:
col++
else:
row++
else:
row++
col--
else:
if row == 0 or col == width:
goingDown = true
if col == width:
row++
else:
col++
else:
row--
col++
return result
Time & Space Complexity
- Time: O(n) where n is the total number of elements in the 2D array. Each element is visited exactly once.
- Space: O(n) for the output array. The traversal itself uses O(1) auxiliary space.
Key Insights
- The order of boundary checks matters. When at a corner (e.g., bottom-left), the row boundary takes priority over the column boundary for "going down," and vice versa for "going up."
- There are only two directions, and each direction has exactly two boundary conditions to handle.
- This pattern generalizes to any rectangular matrix, not just square ones.
Edge Cases
- Single row matrix: the result is just the row in order.
- Single column matrix: the result is just the column in order.
- Single element matrix: return that single element.
- 1xN or Nx1 matrices: the zigzag degenerates into a simple linear traversal.
- Non-square matrices: boundary conditions must account for different heights and widths.