How Spiral Matrix actually works
Spiral traversal is not about direction-changing tricks - it is about four boundaries closing in. top, bottom, left, right fence the block of cells not yet visited; each pass walks one edge of that fence and then pulls it inward. When the fence closes, every cell has been emitted exactly once.
Four boundaries fence the grid
top = 0, bottom = rows - 1, left = 0, right = cols - 1: the fence starts around the whole matrix. The invariant the player tracks is the spiral's whole claim: cells emitted so far were emitted exactly once, and everything inside the fence is still unvisited.
Walk the top edge
Emit row `top` from left to right. This edge is now spent - which is precisely why the next step can shrink the fence without losing anything.
Pull the fence in
top += 1 (and later right -= 1, bottom -= 1, left += 1) retires the walked edge. The two if-guards before the bottom and left walks are the subtle part: after shrinking, the fence may have collapsed - a single-row or single-column remainder - and walking a collapsed edge would emit cells twice. The guards are what keep the invariant true.
Down the right edge
Emit column `right` from the new top down to bottom. Note it starts from the NEW top - the shrink that just happened is what stops the corner cell from being emitted twice. Same pattern as before: walk the edge, then retire it.
Back along the bottom - if it still exists
Guarded by top <= bottom: in a matrix with a single remaining row, the top walk already consumed it, and walking 'the bottom' would re-emit the same cells in reverse. The guard is not defensive style - remove it and the output is wrong on any non-square matrix.
Up the left edge - same guard, other axis
Guarded by left <= right for the single-column case. After this the loop returns to walk-right with a strictly smaller fence.
The fence closes
When top > bottom or left > right, no unvisited block remains. The emitted order holds every cell exactly once - m x n appends, O(m*n) time, O(1) extra space beyond the output.
Common confusions
Why do only two of the four walks have guards?
The first two walks (right, down) are always valid when the loop condition holds. The second two retrace the SAME row or column when only one remains - the guards skip exactly those double-walks. Symmetric guards on all four would be harmless but redundant, and understanding why is understanding the algorithm.
Is there a rotate-the-matrix trick instead?
Yes - emit the top row, rotate the rest counterclockwise, repeat. Elegant to say, O(m*n) extra work per rotation to do. The boundary walk is what you would ship.