题意描述
给定一个 $m$ 行 $n$ 列的矩阵
matrix,按照顺时针螺旋顺序,返回矩阵中的所有元素。
函数参数解释
该函数名为
spiralOrder,返回值为
int*,即返回一个指向整型数组的指针。
-
int** matrix:二级指针,指向一个包含 $m$ 个元素的一级指针数组,每个一级指针指向一个包含 $n$ 个元素的整型数组。即表示一个 $m \times n$ 的矩阵。
-
int matrixSize:输入的二维数组中元素个数 $m$。
-
int* matrixColSize:一级指针,指向一个包含 $m$ 个元素的整型数组,每个元素表示二维数组中对应行的元素个数 $n$。
-
int* returnSize:一级指针,指向一个整型数组,用来存放按照顺时针螺旋顺序遍历矩阵得到的元素,数组长度为矩阵中元素个数 $m \times n$。
代码逻辑解析
该函数采用模拟法,按照顺时针方向遍历矩阵,依次添加元素到返回数组
returnSize 中,直到遍历完所有元素。
首先,定义变量
flag 表示当前已经遍历的元素个数,初始值为 0;定义变量
t、
d、
l、
r 分别表示上、下、左、右四个边界的初始位置。
然后,进入主循环,条件为
flag < m * n,即遍历的元素个数小于矩阵中元素的总个数,就一直循环。
循环内部,按照顺时针方向遍历矩阵,并将遍历到的元素添加到返回数组
returnSize 中。具体地,分为四个方向遍历:
- 从上往右:遍历上边界的元素,添加到
returnSize 中。遍历完后,将上边界向下移动一行。
- 从右往下:遍历右边界的元素,添加到
returnSize 中。遍历完后,将右边界向左移动一列。
- 从下往左:遍历下边界的元素,添加到
returnSize 中。遍历完后,将下边界向上移动一行。
- 从左往上:遍历左边界的元素,添加到
returnSize 中。遍历完后,将左边界向右移动一列。
最后,返回
returnSize 指针。
代码问题
该代码存在以下几个问题:
1. 在第 13 行,变量
r 的初始值应该为
n - 1 而不是
m - 1。
2. 在第 23 行,循环条件应该为
i >= l,而不是
i < r。
3. 在第 29 行,循环条件应该为
i >= d,而不是
i < r。
4. 在第 35 行,循环条件应该为
i <= r,而不是
i < r。
5. 循环结束后,返回的
returnSize 数组长度不一定等于矩阵中元素个数 $m \times n$,因为可能存在重复添加或未添加完全的情况。
修复以上问题后,代码如下:
- int* spiralOrder(int** matrix, int matrixSize, int* matrixColSize, int* returnSize) {
- int flag = 0;
- int m = matrixSize, n = matrixColSize[0];
- int t = 0, d = m - 1;
- int l = 0, r = n - 1;
-
- while (flag < m * n)
- {
- for (int i = l; i <= r && flag < m * n; i++)
- {
- returnSize[flag++] = matrix[t][i];
- }
- t++;
-
- for (int i = t; i <= d && flag < m * n; i++)
- {
- returnSize[flag++] = matrix[i][r];
- }
- r--;
-
- for (int i = r; i >= l && flag < m * n; i--)
- {
- returnSize[flag++] = matrix[d][i];
- }
- d--;
-
- for (int i = d; i >= t && flag < m * n; i--)
- {
- returnSize[flag++] = matrix[i][l];
- }
- l++;
- }
-
- return returnSize;
- }
复制代码
补充说明
以上是代码逻辑上的问题,实际上还存在一些细节可以进行优化,例如:
1. 可以省去循环内部的判断
flag < m * n,改为在循环开始前直接计算需要循环的次数,即
int total = m * n;,然后循环条件改为
while (flag < total),可以提高代码可读性和运行效率。
2. 在循环结束后,需要将返回数组
returnSize 的长度设置为遍历的元素个数
flag,这样才可以确保返回的数组长度正确。
球一个最佳答案谢谢啦!这对我非常重要!

