1. 题目理解与思路选择
先聊清楚这道题到底在做什么。LeetCode 885 "Spiral Matrix III 螺旋矩阵 III",属于典型的模拟题,面试中出现的频率不算特别高,但一旦出现,很容易让人卡住。因为它的遍历起点不在矩阵的左上角,而是矩阵内部的任意一点,甚至可能在矩阵外(虽然原题保证了起点的行列坐标一定在矩阵范围内)。这就意味着你没法用常规的"按圈收缩边界"或者"按层遍历"的思路去处理,老老实实模拟每一步行走,反而是最直接、最不容易出错的方案。
题目的实际要求是这样的:给定 rows 和 cols 表示矩阵的行数和列数,再给定 (rStart, cStart) 作为起始坐标,要求从起点出发,按照顺时针螺旋的顺序走遍矩阵中所有格子,返回按访问顺序排列的所有格子坐标。注意,螺旋路径本身是无限延伸的,但我们只把落在矩阵范围内的坐标收集起来,直到收集满 rows * cols 个坐标为止。
我最初做这道题的时候,第一反应是"能不能像 LeetCode 54 螺旋矩阵那样,用上下左右四个边界不断收缩来处理"。但仔细一想就发现这条路走不通:常规螺旋遍历要求从左上角开始,把矩阵一层层剥开,边界收缩的逻辑非常清晰;但这里起点是任意的,如果还按照"先走最外圈、再走内圈"的思路,你会发现根本没法定义"第一圈"的边界在哪里。起点在中间,螺旋的圈是一层一层向外扩的,这和从外向内剥是完全相反的遍历逻辑。
所以这道题的核心思路只有一个:模拟行走。不要试图找什么数学公式直接计算每个坐标,而是老老实实按照螺旋的路线一步步走,每走一步判断当前位置是否在矩阵内,如果在就记录,走满全部格子就停止。好在这种模拟的规律性很强,方向变化和步长变化都有一套固定的节奏,代码写起来并不复杂。
这道题适合谁来练?我觉得有三类人值得做一遍:第一类是刚开始刷 LeetCode 数组模拟类题目的新手,这道题能帮你加深对方向数组的理解;第二类是准备面试、想在白板上快速写出无 Bug 代码的同学,这道题的边界条件非常典型,很容易暴露粗心的问题;第三类是已经刷过 54、59 题,想系统总结螺旋遍历模板的选手,做这道题能把整个螺旋遍历的体系串起来。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 螺旋规律拆解与核心原理
2.1 步长的变化规律
模拟行走的第一件事,就是搞清楚螺旋的每一步到底该怎么走。从起点出发,按照顺时针方向,行走的顺序是:向东走 1 步,向南走 1 步,向西走 2 步,向北走 2 步,再向东走 3 步,向南走 3 步,向西走 4 步,向北走 4 步……以此类推。
注意这里的关键规律:方向按照"东南西北"的顺序循环变化,步长则是每走两个方向增加 1。也就是说,1 步使用两次(东、南),2 步使用两次(西、北),3 步使用两次(东、南),4 步使用两次(西、北)。为什么是这个规律?因为标准的顺时针螺旋线,每转半圈(即两个方向),半径就会扩大 1。你可以想象一只蜗牛顺时针爬行,每转 180 度,离起点的距离就会增加一格。
我第一次写的时候差点搞错,下意识以为"每走一个方向就步长加 1",结果螺旋半径涨得太快,路径全乱了。所以要刻在脑子里:步长是每经过两个方向才加 1,而不是每个方向加 1。在代码实现里,最优雅的处理方式是外层循环控制步长,中间层循环让每个步长走两个方向,内层循环真正走步。
还有一个容易困惑的点:起始方向到底是哪个方向?题目要求顺时针螺旋,很多教程默认从"向右"开始。这其实和螺旋的定义有关。当你从任意一点出发画一个顺时针向外扩张的螺旋时,第一条边一定是向右的。这一点不用死记,你可以自己在纸上画一画:从中心点出发,如果先向右走 1 步,再向下走 1 步,再向左走 2 步,再向上走 2 步,画出来就是一个标准的顺时针外扩螺旋。如果你从向下开始,画出来虽然也是螺旋,但整体旋转了 90 度,遍历顺序就完全不同了。题目要求的是固定顺序,所以方向数组的排列必须是"右、下、左、上"。
