Print Matrix in Spiral Manner
Problem and examples
Given a 2D matrix, your task is to print all its elements in a spiral order starting from the top-left corner and moving clockwise layer by layer.
In spiral order, you start by printing the top row, then the rightmost column, then the bottom row in reverse, and finally the leftmost column from bottom to top. This process is repeated for the inner layers until all elements are printed.
If the matrix is empty or has no elements, the output should be an empty list.
| Input Matrix | Spiral Output | Description |
|---|---|---|
| [[1, 2, 3], [4, 5, 6], [7, 8, 9]] | [1, 2, 3, 6, 9, 8, 7, 4, 5] | 3x3 square matrix, classic spiral flow |
| [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]] | [1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7] | 3x4 rectangular matrix (more columns) |
| [[1], [2], [3], [4]] | [1, 2, 3, 4] | Single column matrix (4x1) |
| [[1, 2, 3, 4]] | [1, 2, 3, 4] | Single row matrix (1x4) |
| [[5]] | [5] | Single element matrix |
| [] | [] | Empty matrix, no elements to print |
Explore Print a Matrix in Spiral Order
Load an example or enter your own input. Use the player controls to follow each change.
Understanding the Problem
We are given a 2D matrix and asked to print its elements in a spiral order. That means starting from the top-left corner, we go right along the top row, then down the rightmost column, then left along the bottom row, then up the leftmost column—repeating this process inward like peeling layers of an onion until all elements are visited.
For a beginner, think of walking around the boundary of the matrix, one layer at a time, and collecting the numbers in the order you walk.
Step-by-Step Solution with Example
step 1: Initialize boundaries
We define four variables to represent the current unvisited part of the matrix:
top– the index of the first row not yet printedbottom– the index of the last row not yet printedleft– the index of the first column not yet printedright– the index of the last column not yet printed
step 2: Traverse in spiral order
We use a loop and at each iteration, follow this order:
- Go left to right across the top row
- Go top to bottom along the rightmost column
- If rows remain, go right to left along the bottom row
- If columns remain, go bottom to top along the leftmost column
After completing a side, update the boundary variables to move inward (e.g., top++, right--, etc.).
step 3: Continue until all elements are visited
The loop continues as long as top ≤ bottom and left ≤ right. This ensures we don't go beyond the unvisited region.
step 4: Example walk-through
Consider this 3x3 matrix:
[ [1, 2, 3],
[4, 5, 6],
[7, 8, 9] ]
Spiral order traversal:
- Top row: 1, 2, 3
- Right column: 6, 9
- Bottom row (reversed): 8, 7
- Left column (upward): 4
- Remaining element: 5
Output: [1, 2, 3, 6, 9, 8, 7, 4, 5]
Edge Cases
- Empty matrix: No elements to print. Return an empty list.
- Single element: Just return that one value.
- Single row: Only traverse left to right.
- Single column: Only traverse top to bottom.
- More rows than columns: Spiral will loop deeper vertically.
- More columns than rows: Spiral will loop wider horizontally.
Finally
This spiral traversal technique ensures we visit each element exactly once. It's intuitive when we think in terms of peeling layers, and it works efficiently in O(m × n) time for an m x n matrix. For beginners, always visualize the movement and update of boundaries, and use dry runs with small matrices to build confidence.
- Given a 2D matrix of size
m x n. - Initialize four variables:
top = 0,bottom = m - 1,left = 0,right = n - 1. - Traverse the matrix in a spiral form while
top <= bottomandleft <= right: - → Traverse from
lefttorightacross thetoprow and incrementtop. - → Traverse from
toptobottomalong therightcolumn and decrementright. - → If
top <= bottom, traverse fromrighttoleftacross thebottomrow and decrementbottom. - → If
left <= right, traverse frombottomtotopalong theleftcolumn and incrementleft. - Repeat until all elements are printed.
Implementation and efficiency
C implementation
#include <stdio.h>
void spiralOrder(int rows, int cols, int matrix[rows][cols]) {
int top = 0, bottom = rows - 1;
int left = 0, right = cols - 1;
while (top <= bottom && left <= right) {
for (int i = left; i <= right; i++) printf("%d ", matrix[top][i]);
top++;
for (int i = top; i <= bottom; i++) printf("%d ", matrix[i][right]);
right--;
if (top <= bottom) {
for (int i = right; i >= left; i--) printf("%d ", matrix[bottom][i]);
bottom--;
}
if (left <= right) {
for (int i = bottom; i >= top; i--) printf("%d ", matrix[i][left]);
left++;
}
}
}
int main() {
int matrix[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
printf("Spiral Order: ");
spiralOrder(3, 3, matrix);
return 0;
}C++ implementation
#include <iostream>
#include <vector>
using namespace std;
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int> result;
if (matrix.empty()) return result;
int top = 0, bottom = matrix.size() - 1;
int left = 0, right = matrix[0].size() - 1;
while (top <= bottom && left <= right) {
for (int i = left; i <= right; i++) result.push_back(matrix[top][i]);
top++;
for (int i = top; i <= bottom; i++) result.push_back(matrix[i][right]);
right--;
if (top <= bottom) {
for (int i = right; i >= left; i--) result.push_back(matrix[bottom][i]);
bottom--;
}
if (left <= right) {
for (int i = bottom; i >= top; i--) result.push_back(matrix[i][left]);
left++;
}
}
return result;
}
int main() {
vector<vector<int>> matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
vector<int> result = spiralOrder(matrix);
cout << "Spiral Order: ";
for (int num : result) cout << num << " ";
return 0;
}Python implementation
def spiral_order(matrix):
result = []
if not matrix:
return result
top, bottom = 0, len(matrix) - 1
left, right = 0, len(matrix[0]) - 1
while top <= bottom and left <= right:
for i in range(left, right + 1):
result.append(matrix[top][i])
top += 1
for i in range(top, bottom + 1):
result.append(matrix[i][right])
right -= 1
if top <= bottom:
for i in range(right, left - 1, -1):
result.append(matrix[bottom][i])
bottom -= 1
if left <= right:
for i in range(bottom, top - 1, -1):
result.append(matrix[i][left])
left += 1
return result
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print("Spiral Order:", spiral_order(matrix))Java implementation
import java.util.*;
public class SpiralMatrix {
public static List<Integer> spiralOrder(int[][] matrix) {
List<Integer> result = new ArrayList<>();
if (matrix.length == 0) return result;
int top = 0, bottom = matrix.length - 1;
int left = 0, right = matrix[0].length - 1;
while (top <= bottom && left <= right) {
for (int i = left; i <= right; i++) result.add(matrix[top][i]);
top++;
for (int i = top; i <= bottom; i++) result.add(matrix[i][right]);
right--;
if (top <= bottom) {
for (int i = right; i >= left; i--) result.add(matrix[bottom][i]);
bottom--;
}
if (left <= right) {
for (int i = bottom; i >= top; i--) result.add(matrix[i][left]);
left++;
}
}
return result;
}
public static void main(String[] args) {
int[][] matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
System.out.println("Spiral Order: " + spiralOrder(matrix));
}
}JavaScript implementation
function spiralOrder(matrix) {
const result = [];
if (!matrix.length) return result;
let top = 0, bottom = matrix.length - 1;
let left = 0, right = matrix[0].length - 1;
while (top <= bottom && left <= right) {
for (let i = left; i <= right; i++) result.push(matrix[top][i]);
top++;
for (let i = top; i <= bottom; i++) result.push(matrix[i][right]);
right--;
if (top <= bottom) {
for (let i = right; i >= left; i--) result.push(matrix[bottom][i]);
bottom--;
}
if (left <= right) {
for (let i = bottom; i >= top; i--) result.push(matrix[i][left]);
left++;
}
}
return result;
}
const matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
console.log("Spiral Order:", spiralOrder(matrix));Go implementation
package main
import (
"fmt"
)
func spiralOrder(matrix [][]int) []int {
result := []int{}
if len(matrix) == 0 {
return result
}
top, bottom := 0, len(matrix)-1
left, right := 0, len(matrix[0])-1
for top <= bottom && left <= right {
for i := left; i <= right; i++ {
result = append(result, matrix[top][i])
}
top++
for i := top; i <= bottom; i++ {
result = append(result, matrix[i][right])
}
right--
if top <= bottom {
for i := right; i >= left; i-- {
result = append(result, matrix[bottom][i])
}
bottom--
}
if left <= right {
for i := bottom; i >= top; i-- {
result = append(result, matrix[i][left])
}
left++
}
}
return result
}
func main() {
matrix := [][]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
fmt.Print("Spiral Order: ", spiralOrder(matrix))
}Rust implementation
fn spiral_order(matrix: Vec<Vec<i32>>) -> Vec<i32> {
let mut result = Vec::new();
if matrix.is_empty() { return result; }
let (mut top, mut bottom) = (0, matrix.len() as isize - 1);
let (mut left, mut right) = (0, matrix[0].len() as isize - 1);
while top <= bottom && left <= right {
for i in left..=right {
result.push(matrix[top as usize][i as usize]);
}
top += 1;
for i in top..=bottom {
result.push(matrix[i as usize][right as usize]);
}
right -= 1;
if top <= bottom {
for i in (left..=right).rev() {
result.push(matrix[bottom as usize][i as usize]);
}
bottom -= 1;
}
if left <= right {
for i in (top..=bottom).rev() {
result.push(matrix[i as usize][left as usize]);
}
left += 1;
}
}
result
}
fn main() {
let matrix = vec![vec![1,2,3], vec![4,5,6], vec![7,8,9]];
let result = spiral_order(matrix);
println!("Spiral Order: {:?}", result);
}Kotlin implementation
fun spiralOrder(matrix: Array<IntArray>): List<Int> {
val result = mutableListOf<Int>()
if (matrix.isEmpty()) return result
var top = 0
var bottom = matrix.size - 1
var left = 0
var right = matrix[0].size - 1
while (top <= bottom && left <= right) {
for (i in left..right) result.add(matrix[top][i])
top++
for (i in top..bottom) result.add(matrix[i][right])
right--
if (top <= bottom) {
for (i in right downTo left) result.add(matrix[bottom][i])
bottom--
}
if (left <= right) {
for (i in bottom downTo top) result.add(matrix[i][left])
left++
}
}
return result
}
fun main() {
val matrix = arrayOf(
intArrayOf(1, 2, 3),
intArrayOf(4, 5, 6),
intArrayOf(7, 8, 9)
)
println("Spiral Order: ${spiralOrder(matrix)}")
}TypeScript implementation
function spiralOrder(matrix: number[][]): number[] {
const result: number[] = [];
if (matrix.length === 0) return result;
let top = 0, bottom = matrix.length - 1;
let left = 0, right = matrix[0].length - 1;
while (top <= bottom && left <= right) {
for (let i = left; i <= right; i++) result.push(matrix[top][i]);
top++;
for (let i = top; i <= bottom; i++) result.push(matrix[i][right]);
right--;
if (top <= bottom) {
for (let i = right; i >= left; i--) result.push(matrix[bottom][i]);
bottom--;
}
if (left <= right) {
for (let i = bottom; i >= top; i--) result.push(matrix[i][left]);
left++;
}
}
return result;
}
const matrix: number[][] = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
console.log("Spiral Order:", spiralOrder(matrix));