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

Four-boundary spiral with direction cycling
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 result

Common follow-up questions