THN Interview Prep

54. Spiral Matrix

At a Glance

  • Topic: arrays-hashing
  • Pattern: Layered traversal
  • Difficulty: Medium
  • Companies: Amazon, Google, Meta, Microsoft, Apple
  • Frequency: High
  • LeetCode: 54

Problem (one-liner)

Given matrix with height rows and width columns, return all elements in clockwise spiral order starting from top-left.

Recognition Cues

  • "Spiral order", "clockwise"
  • Shrink boundaries: top, bottom, left, right after each edge sweep

Diagram

At-a-glance flow (replace with problem-specific Mermaid as you refine this note). camelCase node IDs; no spaces in IDs.

Loading diagram…

Approaches

  • Brute force — simulate direction with visited map — O(mn) time / O(mn) space.
  • Better — same without visited using layer shrinking — O(1) extra.
  • Optimal — four boundaries while top <= bottom && left <= rightO(mn) time / O(1) extra.

Optimal Solution

Go

package main

func spiralOrder(matrix [][]int) []int {
	if len(matrix) == 0 {
		return nil
	}
	height := len(matrix)
	width := len(matrix[0])
	result := make([]int, 0, height*width)
	top := 0
	bottom := height - 1
	left := 0
	right := width - 1
	for top <= bottom && left <= right {
		for col := left; col <= right; col++ {
			result = append(result, matrix[top][col])
		}
		top++
		for row := top; row <= bottom; row++ {
			result = append(result, matrix[row][right])
		}
		right--
		if top > bottom {
			break
		}
		for col := right; col >= left; col-- {
			result = append(result, matrix[bottom][col])
		}
		bottom--
		if left > right {
			break
		}
		for row := bottom; row >= top; row-- {
			result = append(result, matrix[row][left])
		}
		left++
	}
	return result
}

JavaScript

function spiralOrder(matrix) {
	if (matrix.length === 0) {
		return [];
	}
	const height = matrix.length;
	const width = matrix[0].length;
	const result = [];
	let top = 0;
	let bottom = height - 1;
	let left = 0;
	let right = width - 1;
	while (top <= bottom && left <= right) {
		for (let col = left; col <= right; col++) {
			result.push(matrix[top][col]);
		}
		top++;
		for (let row = top; row <= bottom; row++) {
			result.push(matrix[row][right]);
		}
		right--;
		if (top > bottom) {
			break;
		}
		for (let col = right; col >= left; col--) {
			result.push(matrix[bottom][col]);
		}
		bottom--;
		if (left > right) {
			break;
		}
		for (let row = bottom; row >= top; row--) {
			result.push(matrix[row][left]);
		}
		left++;
	}
	return result;
}

Walkthrough

matrix = [[1,2,3],[4,5,6],[7,8,9]]

layer stepedgeappended valuesbounds after
1top row1,2,3top=1
2right col6,9right=1
3bottom row8,7bottom=1
4left col4left=1
5inner top5done

Output [1,2,3,6,9,8,7,4,5].

Edge Cases

  • Single row — only top sweep; watch duplicate vertical passes.
  • Single column — similar symmetry breaks.
  • 1×1 matrix.

Pitfalls

  • After shrinking top/right, inner row/column may be empty — need top <= bottom checks before vertical legs.
  • Off-by-one when advancing top before right column.

Similar Problems

Variants

  • Spiral Matrix II — fill n×n by spiral.
  • Counter-clockwise — reverse edge order.

Mind-Map Tags

#matrix #spiral #layer #boundaries #simulation

Last updated on

Spotted something unclear or wrong on this page?

On this page