题目描述
力扣第 54 题 —— 螺旋矩阵,要求从矩阵的左上角开始,按顺时针方向逐层遍历矩阵中的所有元素,并以一维数组的形式返回结果。
解题思路
这道题可以用模拟法解决,通过维护矩阵的边界(上下左右四个方向)来实现螺旋顺序的输出。
代码实现与逐行详解
int* spiralOrder(int** matrix, int matrixSize, int* matrixColSize, int* returnSize) {
- 函数签名:返回一维数组形式的螺旋矩阵结果。
matrix
: 输入矩阵,二维数组。matrixSize
: 矩阵的行数。matrixColSize
: 矩阵每行的列数数组。returnSize
: 返回数组的大小。
if (matrixSize == 0 || matrixColSize[0] == 0) {
*returnSize = 0;
return NULL;
}
- 边界判断:如果矩阵为空,直接返回
NULL
。
*returnSize = matrixSize * matrixColSize[0];
int* result = (int*)malloc(sizeof(int) * (*returnSize));
if (!result) {
return NULL; // 内存分配失败
}
- 初始化结果数组:根据矩阵总元素数量分配动态内存。
int left = 0, right = matrixColSize[0] - 1, top = 0, bottom = matrixSize - 1;
int index = 0;
- 定义边界变量
left
、right
、top
、bottom
,以及当前输出位置的索引index
。
螺旋遍历逻辑
while (index < *returnSize) {
- 通过
while
循环逐步缩小矩阵边界,输出所有元素。
- 从左到右遍历
for (int i = left; i <= right && index < *returnSize; i++) {
result[index++] = matrix[top][i];
}
top++;
- 从左到右遍历当前
top
行,将该行的元素加入结果,并向下收缩top
边界。
- 从上到下遍历
for (int i = top; i <= bottom && index < *returnSize; i++) {
result[index++] = matrix[i][right];
}
right--;
- 从上到下遍历当前
right
列,加入结果,并向左收缩right
边界。
- 从右到左遍历
for (int i = right; i >= left && index < *returnSize; i--) {
result[index++] = matrix[bottom][i];
}
bottom--;
- 从右到左遍历当前
bottom
行,加入结果,并向上收缩bottom
边界。
- 从下到上遍历
for (int i = bottom; i >= top && index < *returnSize; i--) {
result[index++] = matrix[i][left];
}
left++;
- 从下到上遍历当前
left
列,加入结果,并向右收缩left
边界。
返回结果
return result;
}
- 最终返回结果数组。
主函数测试
int main() {
// ...(省略,见完
整代码部分)
}
测试用例中定义了一个
3
×
4
3 \times 4
3×4 的矩阵,程序会输出其螺旋顺序:1 2 3 4 8 12 11 10 9 5 6 7
。
复杂度分析
- 时间复杂度: O ( m ⋅ n ) O(m \cdot n) O(m⋅n),其中 m m m 是矩阵行数, n n n 是矩阵列数。每个元素被遍历一次。
- 空间复杂度: O ( m ⋅ n ) O(m \cdot n) O(m⋅n),用于存储结果数组。
输出结果
螺旋矩阵输出结果:
1 2 3 4 8 12 11 10 9 5 6 7