螺旋矩阵
解析函数形参
- 分析理解函数形参,我们才能更好的理解题意,从而实现代码
- 我们先来看看题目给的函数:
/** * 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; }