鱼C论坛

 找回密码
 立即注册
查看: 566|回复: 2

[已解决]螺旋矩阵

[复制链接]
发表于 2023-10-31 20:34:53 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
题目:给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
代码:
int* spiralOrder(int** matrix, int matrixSize, int* matrixColSize, int* returnSize){
    int flag = 0;
    int m = matrixSize, n = matrixColSize[0];
    int t = m - 1, d = 0;
    int l = 0, r = m - 1;
   
    while (flag < m * n)
    {
        for (int i = 0; i < r; i++)
        {
            returnSize[flag++] = matrix[t][i];
        }
        t--;
        
        for (int i = t - 1; i >= 0; i--)
        {
            returnSize[flag++] = matrix[i][r];
        }
        r--;
        
        for (int i = r - 1; i >= 0; i--)
        {
            returnSize[flag++] = matrix[d][i];
        }
        d++;
        
        for (int i = 0; i < r; i++)
        {
            returnSize[flag++] = matrix[i][l];
        }
        l++;
    }
   
    return returnSize;
}
请问代码有哪些bug,函数中各个参数是什么意思?
最佳答案
2023-10-31 20:35:45
题意描述

给定一个 $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;定义变量 tdlr 分别表示上、下、左、右四个边界的初始位置。

然后,进入主循环,条件为 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,这样才可以确保返回的数组长度正确。

球一个最佳答案谢谢啦!这对我非常重要!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-10-31 20:35:01 | 显示全部楼层
代码中存在两个bug:
1. 在第一个for循环中,循环条件应该是i <= r,而不是i < r。
2. 在第三个for循环中,循环条件应该是i >= l,而不是i >= 0。

函数中各个参数的意思如下:
· matrix:一个二维数组,表示输入的矩阵。
· matrixSize:一个整数,表示矩阵的行数。
· matrixColSize:一个整型指针,表示矩阵的列数。由于矩阵的列数可以不同,所以这里使用指针来表示。
· returnSize:一个整型指针,表示返回结果的大小。函数通过修改该指针指向的值来返回结果。
函数的返回值是一个整型指针,指向返回结果的数组。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-31 20:35:45 | 显示全部楼层    本楼为最佳答案   
题意描述

给定一个 $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;定义变量 tdlr 分别表示上、下、左、右四个边界的初始位置。

然后,进入主循环,条件为 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,这样才可以确保返回的数组长度正确。

球一个最佳答案谢谢啦!这对我非常重要!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-24 03:08

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表