一、题目描述
给你一个 m 行 n 列 的矩阵 matrix ,请按照 顺时针螺旋顺序,返回矩阵中的所有元素。
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
示例 2:
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 10
-100 <= matrix[i][j] <= 100
二、解题思路
这道题的核心思想是 模拟螺旋遍历过程。
我们可以维护 四个边界:
top 上边界
bottom 下边界
left 左边界
right 右边界
每一轮按照 顺时针方向遍历四条边:
1. 左 → 右 (遍历 top 行)
2. 上 → 下 (遍历 right 列)
3. 右 → 左 (遍历 bottom 行)
4. 下 → 上 (遍历 left 列)
遍历完成后 收缩边界:
top++
right--
bottom--
left++
注意:
为了防止矩阵只有一行或一列导致 重复遍历,在执行第 3 和第 4 步时需要判断边界。
if (top <= bottom)
if (left <= right)
三、遍历过程示例
矩阵:
1 2 3
4 5 6
7 8 9
遍历顺序:
第一轮:
1 → 2 → 3
↓
6
↓
9 ← 8 ← 7
↑
4
第二轮:
5
最终结果:
[1,2,3,6,9,8,7,4,5]
四、C语言代码实现
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* spiralOrder(int** matrix, int matrixSize, int* matrixColSize, int* returnSize) {
int m = matrixSize;
int n = matrixColSize[0];
*returnSize = m * n;
int* res = (int*)malloc(sizeof(int) * (*returnSize));
int top = 0;
int bottom = m - 1;
int left = 0;
int right = n - 1;
int k = 0;
while (top <= bottom && left <= right) {
// 左 -> 右
for (int i = left; i <= right; i++)
res[k++] = matrix[top][i];
top++;
// 上 -> 下
for (int i = top; i <= bottom; i++)
res[k++] = matrix[i][right];
right--;
// 右 -> 左
if (top <= bottom) {
for (int i = right; i >= left; i--)
res[k++] = matrix[bottom][i];
bottom--;
}
// 下 -> 上
if (left <= right) {
for (int i = bottom; i >= top; i--)
res[k++] = matrix[i][left];
left++;
}
}
return res;
}
五、复杂度分析
时间复杂度
O(m × n)
每个元素只会被访问一次。
空间复杂度
O(1)
除了返回数组外,没有额外空间。
六、总结
这道题本质是 矩阵模拟遍历问题 ,关键是掌握 四边界收缩模板。
核心步骤:
1. 左 -> 右
2. 上 -> 下
3. 右 -> 左
4. 下 -> 上
每一轮遍历后:
top++
right--
bottom--
left++
并注意 边界判断:
if (top <= bottom)
if (left <= right)
这种 四边界模拟方法 是解决矩阵螺旋类问题的经典模板,在很多面试题中都会出现。