一、问题描述
给定一个m行n列的矩阵,按照顺时针螺旋顺序返回矩阵中的所有元素。例如:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
二、解题思路
采用"边界收缩法":
定义四个边界:上(top)、下(bottom)、左(left)、右(right)
按照右→下→左→上的顺序遍历边界
每完成一个方向遍历后收缩对应边界
当边界交叉时终止循环
三、完整C++代码实现
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
if (matrix.empty()) return {};
vector<int> res;
int m = matrix.size(), n = matrix[0].size();
int top = 0, bottom = m - 1, left = 0, right = n - 1;
while (true) {
// 从左到右遍历上层
for (int i = left; i <= right; ++i)
res.push_back(matrix[top][i]);
if (++top > bottom) break;
// 从上到下遍历右层
for (int i = top; i <= bottom; ++i)
res.push_back(matrix[i][right]);
if (--right < left) break;
// 从右到左遍历下层
for (int i = right; i >= left; --i)
res.push_back(matrix[bottom][i]);
if (--bottom < top) break;
// 从下到上遍历左层
for (int i = bottom; i >= top; --i)
res.push_back(matrix[i][left]);
if (++left > right) break;
}
return res;
}
};
1. 边界初始化
top = 0
:最上层边界
bottom = m-1
:最下层边界
left = 0
:最左层边界
right = n-1
:最右层边界
2. 四步遍历循环
每次循环包含四个方向的遍历:
向右遍历:从left到right遍历top行
向下遍历:从top到bottom遍历right列
向左遍历:从right到left遍历bottom行
向上遍历:从bottom到top遍历left列
每次遍历后都会调整对应边界,直到边界交叉(top>bottom或left>right)时终止。
3. 边界收缩机制
完成向右遍历后,top++(上层下移)
完成向下遍历后,right--(右界左移)
完成向左遍历后,bottom--(下层上移)
完成向上遍历后,left++(左界右移)
五、特殊情况处理
空矩阵:直接返回空结果
单行矩阵:只需一次向右遍历
单列矩阵:只需一次向下遍历
矩形矩阵:能正确处理m≠n的情况
六、复杂度分析
七、总结
螺旋矩阵问题考察了对二维数组遍历的精细控制能力,边界收缩法提供了一种直观且高效的解决方案。通过维护四个边界指针,我们可以像剥洋葱一样层层处理矩阵元素,这种思想也可以应用于其他需要特殊顺序遍历的场景。