54. Spiral Matrix

54. Spiral Matrix

Photo by Li Zhang on Unsplash

Table of contents

Problem Statement

Given an m x n matrix, return all elements of the matrix in spiral order. (link)

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]

Constraints:

  • m == matrix.length

  • n == matrix[i].length

  • 1 <= m, n <= 10

  • -100 <= matrix[i][j] <= 100

Solution

Use four pointers.

  • (left, right) - These two pointers facilitate row iteration from left to right.

  • (top, bottom) - These two pointers facilitate column iteration from top to bottom.

Initially, we gather elements from the first row. Then, we increment the top pointer and move downward. Subsequently, we decrement the right pointer and move leftward. Following that, we decrement the bottom pointer and move upward.

This entire process continues only under the conditions top <= bottom and left <= right.

There are only two edge cases that require special attention: one involving a single row and the other involving a single column.

Example 1 - matrix = [[4,5,1]]

Example 2 - matrix = [[4],[5],[1]]

A specific condition is needed when iterating through a row or column in the opposite directions (right to left or bottom to top), based on these two edge cases.

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        int m = matrix.length;
        int n = matrix[0].length;

        List<Integer> ans = new ArrayList<>();

        int left = 0;
        int right = n-1;
        int top = 0;
        int bottom = m-1;

        //Both row and column indices should be valid
        while(left<=right && top<=bottom){
            for(int i=left; i<=right; i++){
                ans.add(matrix[top][i]);
            }
            top+=1;
            for(int i=top; i<=bottom; i++){
                ans.add(matrix[i][right]);
            }
            right-=1;

            //Only for single column check
            if(top<=bottom){
                for(int i=right; i>=left; i--){
                    ans.add(matrix[bottom][i]);
                }
            }
            bottom-=1;

            //Only for single row check    
            if(left<=right){
                for(int i=bottom; i>=top; i--){
                    ans.add(matrix[i][left]);
                }
            }
            left+=1;
        }
        return ans;
    }
}