#54
中等
高频
迭代法螺旋矩阵
这是一道围绕算法展开的高频练习。建议先掌握「迭代法」这套写法,再结合下方步骤讲解理解状态维护、边界处理和复杂度取舍。
算法
题目分析
这道题表面上是在处理「螺旋矩阵」,但先要想清楚题目到底让你返回什么,以及过程中哪些约束必须一直满足。从题型上看,它主要在考 算法 这些能力。这类题通常不难想到总体方向,真正容易乱的是遍历顺序、边界收缩和状态更新的先后关系。只有先把题目要求翻译成人话,后面的推荐代码才是在实现思路,而不是直接给答案。
接下来怎么看推荐代码: 带着这个理解再看推荐代码时,重点观察这条主线:维护上、下、左、右四条边界,每轮按右、下、左、上的顺序收缩一圈。
推荐代码
推荐解法:迭代法
时间复杂度: O(m*n)
空间复杂度: O(1)
核心思路: 维护上、下、左、右四条边界,每轮按右、下、左、上的顺序收缩一圈。
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> order = new ArrayList<Integer>();
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return order;
}
int rows = matrix.length, columns = matrix[0].length;
boolean[][] visited = new boolean[rows][columns];
int total = rows * columns;
int row = 0, column = 0;
int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
int directionIndex = 0;
for (int i = 0; i < total; i++) {
order.add(matrix[row][column]);
visited[row][column] = true;
int nextRow = row + directions[directionIndex][0], nextColumn = column + directions[directionIndex][1];
if (nextRow < 0 || nextRow >= rows || nextColumn < 0 || nextColumn >= columns || visited[nextRow][nextColumn]) {
directionIndex = (directionIndex + 1) % 4;
}
row += directions[directionIndex][0];
column += directions[directionIndex][1];
}
return order;
}
}结构化讲解
面试时怎么讲
开场思路
这题我会用四边界按层遍历,而不是做复杂方向模拟。
核心过程
- 先初始化当前矩形的四条边界。
- 每轮依次遍历上边、右边、下边、左边。
- 每走完一条边就收缩对应边界。
- 直到边界交错,说明所有元素都访问完。
复杂度总结
时间复杂度 O(m*n),空间复杂度 O(1)。
面试补一句:螺旋矩阵最重要的是“边界收缩”,不是“方向切换”。
核心思路
螺旋遍历不是模拟方向乱走,而是按层剥洋葱。四条边界定义了当前还没访问的矩形区域,每走完一条边就收缩对应边界。
步骤讲解
1
初始化四条边界
用 top、bottom、left、right 表示当前待遍历矩形的上下左右范围。
为什么这样做:后续所有访问都围绕这四条边界展开。
对应代码提示:int top = 0, bottom = m - 1, left = 0, right = n - 1;
2
按四个方向走完当前外圈
依次遍历上边、右边、下边、左边,每次都注意边界是否仍然有效。
为什么这样做:一圈走完后,外层元素就全部输出完了。
对应代码提示:for (int col = left; col <= right; col++) answer.add(matrix[top][col]);
3
每走完一条边就收缩边界
上边走完 top++,右边走完 right--,其余同理。
为什么这样做:收缩后问题规模缩小,下一轮继续处理内层矩形。
对应代码提示:top++; right--; bottom--; left++;
易错点
没有在每个方向前判断边界
单行或单列矩阵时容易重复访问元素。
正确理解:每个方向开始前都先确认
top <= bottom、left <= right。把方向切换写成坐标模拟
容易在边界和已访问状态上写得很乱。
正确理解:优先用四边界分层遍历,更直接也更稳。
收缩边界时机错误
会造成漏访问或重复访问一整行/列。
正确理解:每走完对应方向后立刻收缩对应边界。
复杂度与适用判断
时间复杂度:O(m*n)
空间复杂度:O(1)
比其他方案更好在哪里:比 visited 数组模拟更省空间,也更适合面试手写。
适用判断:矩阵题涉及分层遍历、按圈访问时,优先考虑四边界。
额外提醒
- 每条边走完后都要立即收缩。
动画演示
如果你还没完全看懂,可以展开动画演示。
迭代法动画演示
想看这段解法是怎么一步步运行的,可以展开动画继续观察。
迭代法动画演示
想看这段解法是怎么一步步运行的,可以展开动画继续观察。
准备就绪 - 输入矩阵(行用分号分隔,列用逗号分隔),然后点击开始
动画演示仅在桌面端提供,移动端请优先阅读推荐代码与结构化讲解。