螺旋遍历本质是边界收缩与方向轮转:用top、bottom、left、right四变量动态圈定未访问区,每走完一边即收紧对应边界,并在每轮前检查边界有效性,自然兼容空矩阵、单行、单列等所有形状。

二维数组的螺旋遍历本质是“边界收缩+方向轮转”,不是靠坐标转向或额外标记,而是用四个变量动态圈定未访问区域——上、下、左、右边界。只要每次走完一边就收紧对应边界,并在每轮开始前检查边界是否仍有效,就能自然兼容所有形状:空矩阵、单行、单列、长方阵、正方形,无需特判分支。
用四边界控制遍历节奏
初始化 top = 0, bottom = len(matrix) - 1, left = 0, right = len(matrix[0]) - 1。循环条件为 top ,保证还有可遍历区域。
- 向右走:从
left到right,填入matrix[top][j],之后top += 1 - 向下走:从
top到bottom,填入matrix[i][right],之后right -= 1 - 向左走:从
right到left(含),填入matrix[bottom][j],之后bottom -= 1 - 向上走:从
bottom到top(含),填入matrix[i][left],之后left += 1
每边收尾必须做边界校验
关键不是“走完再判断”,而是在执行某一边前先确认该边还存在。例如向左走前要判断 top ,否则最后一行可能被重复遍历;向上走前要判断 <code>left ,否则最后一列会多走一次。
- 向右后:若
top > bottom,说明已无剩余行,直接退出 - 向下后:若
right ,说明已无剩余列,终止循环 - 向左和向上同理,各自依赖对应的行列边界条件
填充类问题只需反向操作
如果是螺旋填充(如生成螺旋矩阵 II),逻辑完全对称:不是读取值,而是按顺序写入数字 1, 2, 3, …。遍历路径一致,只是把 res.append(...) 换成 matrix[i][j] = num; num += 1。
- 起始数字设为 1,每填一个位置就自增
- 四边顺序不变,边界更新时机也不变
- 同样依赖
top 控制整体循环
避免常见越界陷阱
错误常发生在循环范围写错:比如向左走用了 range(right, left, -1),漏掉 left 位置;或向上走用了 range(bottom, top, -1),漏掉 top 行。正确写法应包含端点:
- 向左:
for j in range(right, left - 1, -1) - 向上:
for i in range(bottom, top - 1, -1) - 所有循环都用
+1或-1显式控制步长和终点,不依赖隐含行为











