每日一题——螺旋矩阵

该文详细解释了一道编程题,涉及如何生成螺旋矩阵。解析了函数参数的作用,特别是`returnSize`和`returnColumnSizes`用于表示二维数组的行数和每行的列数。文章提出了使用循环和边界处理的策略,遵循循环不变量原则,按照左闭右开的思想填充矩阵。最后给出了实现代码。
摘要由CSDN通过智能技术生成

每日一题

螺旋矩阵

题目链接

在这里插入图片描述

解析函数形参

  • 分析理解函数形参,我们才能更好的理解题意,从而实现代码
  • 我们先来看看题目给的函数:
/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** generateMatrix(int n, int* returnSize, int** returnColumnSizes)
  • 可以看到,函数返回的因该是一个二维数组的首地址,n应该是螺旋矩阵的行数和列数,那这个int* returnSize, int** returnColumnSizes又是什么呢?
    • 我们知道,这个函数返回的是二维数组的首地址,那判题器判题时,是用什么来确定这个二维数组的行数,以及每一行的列数呢?靠的就是int* returnSize,和int** returnColumnSizes
    • returnSize传入的是一级指针,因此原来是一个数,所以着可以代表二维数组的行数,returnColunSizes传入的是二级指针,因此原来是一个一维数组,那么这就可以用来储存二维数组每一行所包含的列数了。

思路

  • 这题很明显要利用二维数组和循环来解决问题。

  • 可能很多小伙伴看到这题觉得很简单,直接循环里面各种循环判断,结果出现了各种错误,且改了这里那里又错了。

  • 为了处理这种情况,我们就要遵守循环不变量原则,循环不变量原则就是在循环中坚持根据查找区间的定义来做边界处理,因此我们就要确定循环的区间的范围,以及区间到底是左开右闭还是左闭右开
    在这里插入图片描述

  • 我们可以将这个正方形矩阵看成是多个正方形嵌套而成,那么我们对二维数组进行数据填入时,就可以采用对每个正方形进行数据填入的思想来处理。

    • 这里我们就用左闭右开的思想来解决,如上图,一个正方形里,不同·颜色的数据填入就用不同的循环来实现(从左到右,从上到下,从右到左,从下到上)。

具体步骤

  • 首先我们要申请一个二维数组,用来存储数据,二维数组的大小就是n个一维数组首地址的大小的和(二维数组可以粗略的看成是多个一维数组的集合),继续对这n个一维数组申请内存,大小为n个int的大小(即螺旋矩阵要存n行数据),同时还要确定这n行每一行的列数
int **res = (int **)malloc(sizeof(int*) * n);	//申请一个二维数组
*returnSize = n;		//确定数组行数
* returnColumnSizes = (int *)malloc(sizeof(int) * n);	//申请用来存放每一行的列数的数组的内存
for (int i = 0; i < n; i++) 
{
 res[i] = (int*)malloc(sizeof(int) * n);	//对这n个一维数组申请内存
 (*returnColumnSizes)[i] = n;	//确定这n行每一行的列数
}
  • 定义left=0,right=n-1,top=0,bottom=n-1,分别代表方形的左边,右边,上边,下边,进行循环填入
while(left <= right && top <= bottom)
   {
       if(left == right && top == bottom)	//对中间为一个元素的特殊情况进行处理
           res[left][top] = num;
       for(int j = left; j < right; j++)
           res[top][j] = num++;
       for(int i = top; i < bottom; i++)
           res[i][right] = num++;
       for(int j = right; j > left; j--)
           res[bottom][j] = num++;
       for(int i = bottom; i > top; i--)
           res[i][left] = num++;
       left++;
       right--;
       top++;
       bottom--;
   }

实现代码

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** generateMatrix(int n, int* returnSize, int** returnColumnSizes){
    int **res = (int **)malloc(sizeof(int*) * n);	//申请一个二维数组
    *returnSize = n;		//确定数组行数
    * returnColumnSizes = (int *)malloc(sizeof(int) * n);	//申请用来存放每一行的列数的数组的内存
    for (int i = 0; i < n; i++) 
    {
      res[i] = (int*)malloc(sizeof(int) * n);	//对这n个一维数组申请内存
      (*returnColumnSizes)[i] = n;	//确定这n行每一行的列数
    }
    int num = 1;
    int left = 0, right = n - 1, top = 0, bottom = n - 1;
    while(left <= right && top <= bottom)
    {
        if(left == right && top == bottom)		//对中间为一个元素的特殊情况进行处理
            res[left][top] = num;
        //始终遵循左闭右开
        for(int j = left; j < right; j++)
            res[top][j] = num++;
        for(int i = top; i < bottom; i++)
            res[i][right] = num++;
        for(int j = right; j > left; j--)
            res[bottom][j] = num++;
        for(int i = bottom; i > top; i--)
            res[i][left] = num++;
        //缩小方形
        left++;
        right--;
        top++;
        bottom--;
    }
    return res;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Forward♞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值