Arrays · Medium
36. Spiral Traversal of a Matrix
Topics: Matrix
Solve it on DeVert Campus - free code runner
Problem
Given an r x c matrix, print all its elements in clockwise spiral order starting from the top-left corner, as a single space-separated line.
Input and output
Input: The first line contains r and c, the matrix dimensions. The next r lines each contain c space-separated integers.
Output: Print all matrix elements in clockwise spiral order, space-separated on one line.
Example
Input: 3 3 1 2 3 4 5 6 7 8 9 Output: 1 2 3 6 9 8 7 4 5
Constraints
1 <= r, c <= 100
Key observation
Non-square matrices and edge cases (a single row, a single column, or a matrix with just one cell) are worth testing explicitly - the four-boundary approach handles them correctly only if the loop checks boundaries independently for each of the four sides, not just once per full cycle.
Intuition
Print every element of a grid in a clockwise spiral order, starting from the top-left corner and winding inward.
Brute force: There isn't really a simpler 'brute force' here beyond the boundary-tracking approach itself - attempting it without carefully shrinking boundaries (e.g. trying to compute spiral positions with pure index arithmetic) tends to produce fragile, hard-to-verify code full of off-by-one bugs.
Optimised: Maintaining four explicit, shrinking boundaries (top, bottom, left, right) and always traversing one full side before shrinking that side's boundary inward keeps the logic simple and provably correct - each of the four traversal directions is just a simple straight-line loop between two boundaries.
Better - Four Boundary Pointers, Layer by Layer
Track four shrinking boundaries (top, bottom, left, right). Print the top row left-to-right, then the right column top-to-bottom, then (if rows remain) the bottom row right-to-left, then (if columns remain) the left column bottom-to-top, and move each boundary inward after its side is done; repeat until the boundaries cross. This removes the need for any visited matrix entirely, since the boundaries alone always describe exactly the unvisited region, replacing O(r*c) extra memory with a handful of integer pointers.
Time: O(r*c)
Space: O(1)
Brute Force - Direction Vector With Visited Matrix
Walk through the matrix starting at the top-left, moving in a current direction (right, down, left, up in that cycle) and marking each visited cell in a separate boolean matrix; whenever the next cell in the current direction would go out of bounds or has already been visited, turn 90 degrees clockwise and continue. This correctly traces the spiral by explicitly checking the visited matrix at every step, but that matrix costs as much extra memory as the input itself.
Time: O(r*c)
Space: O(r*c)
Optimal - Single Loop With Direction Array and Boundaries
Combine a direction vector (right, down, left, up) with the same four shrinking boundaries, but drive the whole traversal from one unified loop that outputs a cell, advances in the current direction, and turns (updating the boundary just vacated) whenever the next step would leave the shrinking region - rather than writing four separate directional loops per layer. This keeps the same O(1) extra space as the boundary approach but with simpler, more uniform control flow that handles degenerate single-row or single-column matrices without special-casing.
Time: O(r*c)
Space: O(1)
Step by step
1. Track four shrinking boundaries: top row, bottom row, left column, right column.
2. Traverse the top row from left to right, then shrink the top boundary down by one.
3. Traverse the right column from top to bottom, then shrink the right boundary in by one.
4. Traverse the bottom row from right to left, then shrink the bottom boundary up by one; traverse the left column from bottom to top, then shrink the left boundary in by one - repeat this whole four-sided cycle until the boundaries cross.
Complexity
Time: O(r * c) - every cell of the matrix is visited and printed exactly once.
Space: O(1) extra space beyond the output itself (just the four boundary trackers).
Edge cases
r = 1 or c = 1 (degenerates to printing a single row or column directly); a non-square matrix where r != c; and r = c = 100 (largest, confirming the shrinking-boundary approach is O(r*c)).
Interview tip
Be careful with the loop's TERMINATION condition (when top exceeds bottom, or left exceeds right) - this is the most common source of off-by-one bugs in spiral traversal, especially for non-square or single-row/column matrices.