matrix-traversal

::: info Prerequisites

Before reading this article, you should learn:

:::

Some readers say that after reading many articles on this site, they learned “framework thinking” and can solve most problems that follow a fixed pattern.

But framework thinking is not magic. Some special tricks are like this: if you know them, they are easy; if you don’t, they feel very hard. You can only learn them by doing more problems and summarizing.

In this article, I will share some smart operations on 2D arrays. Just remember the idea. Next time you see a similar problem, you won’t get stuck.

Rotate a Matrix Clockwise / Counterclockwise

Rotating a 2D array is a common interview test question. LeetCode 48, “Rotate Imagearrow-up-right”, is a classic one:

LeetCode 48. Rotate Image

You are given an n x n 2D matrix representing an image, rotate the image by 90 degrees (clockwise).

You have to rotate the image in-placearrow-up-right, which means you have to modify the input 2D matrix directly. DO NOT allocate another 2D matrix and do the rotation.

Example 1:**

Example 2:**

Constraints:

  • n == matrix.length == matrix[i].length

  • 1 <= n <= 20

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

The problem is easy to understand: rotate a 2D matrix 90 degrees clockwise. The hard part is: you must modify it in-place. The function signature is:

How do we rotate a 2D matrix in-place? If you think a bit, it feels complicated. You may think you need to rotate it “layer by layer”:

But for this problem, you need a different idea. Before we talk about the smart solution, let’s warm up with another problem that Google once asked:

You are given a string s with words and spaces. Write an algorithm to reverse the order of words in-place.

For example:

You need to make it:

A common way is: split by spaces, reverse the word list, then join. But that uses extra space, so it is not “in-place”.

The correct trick is: first reverse the whole string s:

Then reverse each word by itself:

Now you reversed the word order in-place. LeetCode 151, “Reverse Words in a Stringarrow-up-right”, is a similar problem.

This trick can be used in other problems too. For example, LeetCode 61, “Rotate Listarrow-up-right”: given a singly linked list, rotate it so every node moves right by k positions.

Example: 1 -> 2 -> 3 -> 4 -> 5, k = 2. The result is 4 -> 5 -> 1 -> 2 -> 3.

For this problem, don’t move nodes one by one. Let me translate it: it really means “move the last k nodes to the head”, right?

Still not clear? Moving the last k nodes to the head means you split the list into the first n - k nodes and the last k nodes, then reverse them in-place, right?

This is the same idea as reversing words in-place. You first reverse the whole list, then reverse the first n - k nodes and the last k nodes.

There are some details. For example, k can be larger than the list length. So you should compute the length n first, then do k = k % n. Then k will be valid and the result will be correct.

If you have time, try this problem yourself. It is not hard, so I won’t show the code here.

Why did I talk about these two problems?

The point is: our “natural” idea is not always the best for a computer; and the computer’s clean idea is not always natural for us. That may be the fun part of algorithms.

Back to rotating an n x n matrix clockwise. The common idea is to find a mapping from old coordinates to new coordinates. But we can try a jump in thinking: do reverse or mirror operations. That can give a new way.

First, mirror the n x n matrix matrix across the main diagonal (top-left to bottom-right):

Then reverse each row:

You will get the matrix rotated 90 degrees clockwise:

Turn this idea into code and you can solve the problem:

You can open the panel below. Click the line let temp = matrix[i][j] many times to see the diagonal mirror step. Then click reverse(row) many times to see each row reversed and get the final answer:

Some readers may ask: if I never did this problem before, how could I think of this?

Yes, if you never saw this type of problem, it’s hard to think of. But now you have seen it. If you know it, it’s easy; if you don’t, it’s hard. You will probably never forget it.

Now let’s extend it: how do we rotate the matrix 90 degrees counterclockwise?

The idea is similar: mirror the matrix across the other diagonal, then reverse each row. That gives the counterclockwise result:

The code is:

Now the rotation problem is solved.

Spiral Traversal of a Matrix

Next, let’s look at LeetCode 54, “Spiral Matrixarrow-up-right”, and see a common way to traverse a 2D matrix:

LeetCode 54. Spiral Matrix

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

Example 1:**

Example 2:**

Constraints:

  • m == matrix.length

  • n == matrix[i].length

  • 1 <= m, n <= 10

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

The key idea is to traverse in the order: right, down, left, up, and use four variables to mark the borders of the unvisited area:

As we traverse in a spiral, the borders shrink, until we finish the whole matrix:

With this idea, writing the code is easy:

You can open the panel below. Click the line while (res.length < m * n) many times to see the spiral traversal from outside to inside:

LeetCode 59, “Spiral Matrix IIarrow-up-right”, is very similar, but reversed: it asks you to generate a matrix in spiral order:

LeetCode 59. Spiral Matrix II

Given a positive integer n, generate an n x n matrix filled with elements from 1 to n^(2) in spiral order.

Example 1:**

Example 2:**

Constraints:

  • 1 <= n <= 20

With the setup above, you can finish it with small code changes:

You can open the panel below. Click the line while (num <= n * n) many times to see the spiral matrix being generated:

Now both spiral matrix problems are solved.

These are some useful 2D array traversal tricks. For other array tricks, see: Prefix Sum Arrayarrow-up-right, Difference Arrayarrow-up-right, Two-Pointer Tricks for Arraysarrow-up-right. For linked list tricks, see: Six Key Tricks for Singly Linked Listsarrow-up-right.

Last updated