The Onion Layer
A hard Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.
- Domain
- Python
- Difficulty
- hard
- Seniority
- L5
- Asked in
- Spirit Airlines
Problem
Given an m x n 2D matrix, return a flat list of all elements in spiral order starting from the top-left corner and moving clockwise.
Peel from the outside in - one ring at a time.
Example 1
Input:
matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output:
[1,2,3,6,9,8,7,4,5]
Example 2
Input:
matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
Output:
[1,2,3,4,8,12,11,10,9,5,6,7]
Worked solution and explanation
Why this problem exists in real interviews
This tests boundary management and directional traversal on a 2D grid. Spiral order requires tracking four shrinking boundaries and switching directions at each turn, revealing whether candidates can manage complex state transitions cleanly.
Break down the requirements
Step 1: Initialize four boundaries
Top row, bottom row, left column, right column. These define the current outermost unvisited ring.
Step 2: Traverse right across the top row
Collect elements from left to right along the top boundary, then increment top.
Step 3: Traverse down the right column
Collect elements from top to bottom along the right boundary, then decrement right.
Step 4: Traverse left across the bottom row
If top has not crossed bottom, collect elements from right to left along the bottom boundary, then decrement bottom.
Step 5: Traverse up the left column
If left has not crossed right, collect elements from bottom to top along the left boundary, then increment left.
Step 6: Repeat until boundaries cross
The loop ends when top > bottom or left > right.
The solution
def spiral_order(matrix):
if not matrix:
return []
result = []
top = 0
bottom = len(matrix) - 1
left = 0
right = len(matrix[0]) - 1
while top <= bottom and left <= right:
for col in range(left, right + 1):
result.append(matrix[top][col])
top += 1
for row in range(top, bottom + 1):
result.append(matrix[row][right])
right -= 1
if top <= bottom:
for col in range(right, left - 1, -1):
result.append(matrix[bottom][col])
bottom -= 1
if left <= right:
for row in range(bottom, top - 1, -1):
result.append(matrix[row][left])
left += 1
return resultCommon follow-up questions
- How would you fill a matrix in spiral order instead of reading it? (Tests reversing the logic: assign values while traversing boundaries.)
- What if the matrix were very large and you needed to access specific positions? (Tests computing the spiral index mathematically without full traversal.)
- How would you generalize to counter-clockwise spiral order? (Tests reordering the four direction passes.)
- What if the matrix had holes (None values) that should be skipped? (Tests adding a filter condition during traversal.)