Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 8

Spiral Matrix Traversal

Recommended resources

Introduction

In our last few lessons, we've built a strong foundation in array and string manipulation, covering techniques like two-pointers and sliding windows. Today, we'll tackle our final topic in this module: traversing a 2D matrix. Specifically, we'll focus on a classic and frequently asked interview problem: traversing a 2D matrix in spiral order.

This problem is an excellent test of your ability to manage boundaries, handle state, and write clean, logical code for grid-based traversals. We will explore two primary strategies to solve this. The first is a straightforward simulation using extra memory to track visited cells. The second, more space-efficient approach involves shrinking the matrix boundaries layer by layer. By the end of this lesson, you'll be equipped to implement both solutions and discuss their trade-offs, a key skill for any coding interview.


Visualizing the Spiral Path

Before diving into code, let's build a strong mental model of what "spiral traversal" means. Given a 2D matrix, the goal is to visit its elements by starting at the top-left corner, moving right across the first row, then down the last column, left across the last row, up the first column, and then repeating this pattern inward.

This image shows a 4x4 matrix and the resulting sequence of elements from a spiral traversal. The path moves clockwise, starting from the outside and moving inward.

A powerful way to conceptualize this is to think of the matrix as being made of concentric layers, like an onion. We "peel" the outermost layer, then the next layer, and so on, until we reach the center.

This visualization breaks down a 5x5 matrix into its outer, inner, and innermost layers. The spiral traversal simply processes these layers in sequence from Layer 1 to Layer 3.

This layer-by-layer intuition forms the basis for the most common and efficient solution to this problem.


Approach 1: Simulation with Direction Vectors

One intuitive way to approach this problem is to simulate the path of a person walking through the matrix. This person needs to know their current position, their current direction, and when to turn.

The logic is as follows:

  1. Start at the top-left corner (0, 0).
  2. Define a sequence of four directions: Right, Down, Left, Up. These can be represented by direction vectors: (0, 1) for right, (1, 0) for down, (0, -1) for left, and (-1, 0) for up.
  3. Keep moving in the current direction, adding each element you visit to your result.
  4. To avoid revisiting cells, use an auxiliary 2D boolean array, visited, of the same size as the matrix. Mark each cell as true after you visit it.
  5. Before taking a step, check if the next cell is either out of bounds or has already been visited. If it is, you know it's time to "turn" 90 degrees clockwise (i.e., switch to the next direction in your sequence).
  6. Repeat this process until you have visited all m * n elements in the matrix.

This simulation approach is very direct. The article "54. Spiral Matrix - In-Depth Explanation" from Algo.monster provides an excellent breakdown of this method.

54. Spiral Matrix - In-Depth Explanation

Please read the "Intuition", "Solution Approach", and "Example Walkthrough" sections of this article.

Focus on the core idea of using direction vectors and a visited matrix. In the Intuition section, understand how the four directions are represented as coordinate changes. Then, in the Solution Approach, follow the step-by-step logic for initializing variables and looping. Finally, trace the process with the 3x3 matrix example to see how the position, direction, and visited status change at each step.

This simulation approach is perfectly valid and easy to reason about. Let's analyze its complexity.

  • Time Complexity: We visit each of the m * n cells exactly once, performing constant-time work at each cell. Therefore, the time complexity is .
  • Space Complexity: The primary consumer of extra space is the visited matrix, which has the same dimensions as the input. This results in a space complexity of .

While correct, the space complexity can be a point of discussion in an interview. A common follow-up question would be: "Can you do it with constant extra space?" This leads us to our second approach.


Approach 2: Layer-by-Layer with Shrinking Boundaries

This approach directly implements the "peeling the onion" intuition we discussed earlier. Instead of tracking every single visited cell, we only need to keep track of the boundaries of the current layer we are traversing.

We can define these boundaries with four variables:

  • top: The row index of the top boundary.
  • bottom: The row index of the bottom boundary.
  • left: The column index of the left boundary.
  • right: The column index of the right boundary.

The algorithm proceeds in a loop, with each iteration printing one full layer:

  1. Traverse Right: Print elements from left to right along the top row. After this, the top boundary has been fully processed, so we increment top.
  2. Traverse Down: Print elements from top to bottom along the right column. After this, decrement right.
  3. Traverse Left: Print elements from right to left along the bottom row. After this, decrement bottom.
  4. Traverse Up: Print elements from bottom to top along the left column. After this, increment left.

We repeat this process as long as our boundaries are valid (i.e., left <= right and top <= bottom). The shrinking of the boundaries ensures we never re-process an element.

The video from the "take U forward" channel provides a fantastic visual explanation of this logic.

Spiral Traversal of a Matrix | Spiral Matrix

This video masterfully explains the shrinking boundaries approach.

First, watch the conceptual breakdown from the observation to understand the pattern of moving right, bottom, left, and top. Then, follow the detailed logic from the implementation idea, where the presenter uses top, bottom, left, and right pointers on a whiteboard to trace the first layer. Finally, see how this translates into code in the coding segment, paying close attention to the while loop condition that controls the traversal.

An important detail is handling matrices that are not square, such as single-row or single-column matrices. For example, after printing the top row and then the right column, the bottom row might already have been processed. The while loop condition (top <= bottom && left <= right) combined with careful checks inside the loop prevents the algorithm from re-printing elements. The "CodeHelp - by Babbar" video offers a robust C++ implementation that correctly handles these cases.

Lecture 23: Introduction to 2D Arrays in C++ || LeetCode Questions

This video provides a clear C++ implementation of the layer-by-layer approach.

Watch the segment on "spiral print" from the explanation of the approach, which reinforces the concept of shrinking boundaries. Then, pay close attention to the coding part from the C++ implementation. The logic of using count and total variables inside the loop is a clever way to ensure you don't print extra elements in non-square matrices.

Let's analyze the complexity of this optimized approach:

  • Time Complexity: Same as before, , because we still visit every element exactly once.
  • Space Complexity: We are only using a few variables (top, bottom, left, right) to store the boundaries. This is constant space, so the complexity is (not counting the space for the output vector). This is a significant improvement and is the expected optimal solution in an interview context.

Conclusion

Today, we've mastered the spiral matrix traversal problem, a staple of coding interviews. You now have two distinct strategies in your arsenal.

Key Takeaways:

  • Spiral Traversal: A process of visiting elements in a 2D matrix in a clockwise, inward-spiraling path.
  • Two Main Approaches:
    1. Simulation: An intuitive method using direction vectors and a visited matrix. It's easy to conceptualize but has a space complexity of .
    2. Layer-by-Layer: A more optimal approach using four pointers (top, bottom, left, right) to define and shrink the boundaries of the matrix. This achieves the same time complexity but with superior space complexity.
  • Boundary Management: The core of the problem lies in correctly updating the boundaries after each part of a layer is traversed to prevent redundant visits.

This lesson concludes our first module on core concepts and array/matrix manipulation. You've learned about complexity analysis, essential C++ STL containers, and powerful algorithmic patterns like two-pointers, sliding windows, and now, spiral traversal.

In our next lesson, we will begin a new module and explore a fundamentally different way of thinking about problems: recursion. This powerful technique will unlock solutions to a whole new class of problems.