文章目录
- 前言
- 解题思路
- 上代码
- 总结
前言
螺旋式排列数组在letcode中属于中等难度的题型,但是对于俺这种道行浅的人再次重新拾起正吃灰的C语言的菜鸟来说确实不容易。其实思路不难,按主要是卡在了二维数组空间的分配问题上,最后调试才将代码修补完整,最后还是想记录一下。
一、什么是螺旋式排列数组?

以上便是(自古文人都是贼!)
是一种由内向外一圈一圈逐渐递增而形成的一个n行n列的正方形矩阵(二维数组)。
letcode-59
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix (顺带题目描述)
二、解题思路
1. 由内向外逐层循环遍历,正方形举证的每条边用一个for循环来遍历;
2. 坚持每条边遍历的规则不变,什么时候行变,什么时候列变,分别用一个变量来对其控制
3. 外层一个for循环来控制转的圈数,内层四个for循环老对四条边进行遍历
4. 遍历的次数为 n/2(原因代码注解给出), 当n为单数时要另外加一个if语句进行判断来讲最后一个元素(最中间那个元素)写入数组当中。
5. 特别特别特别注意这里二维数组空间的分配,不知是否有小伙伴和我一样对二维数组的分配直接简单使用一条malloc来分配就不管了,其实这样是错误的。二维数组与一维数组还是有所区别。二维数组的正确空间分配方法是:先给二维数组整体分配一个空间,然后再在这个整体中对一维数组分配空间;如此才是正确的写法(使用的是二级指针,先分配一维再分配另一维,注意最后要记得free)
给出我自己的草稿(其实重新写画了一遍,hhhh……)

自己有些潦草,将就😊
其实我个人觉得,做这种算法题,如果自己的思路不是很清晰,在纸上自己写一遍,画一下,真的效率会高蛮多,记忆更深刻(个人体会)
代码如下(示例):
#include <stdio.h>
#include <stdlib.h>
/*
* letcode-59
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,
且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix
Notes: 注意二维数组的分配:
动态分配一个n行,m列的二维数组
先动态分配一维数组
p = (int **)malloc(sizeof(int *) * n);
再分配二维
for (i = 0; i < n; i++) {
p[i] = (int *)malloc(sizeof(int) * m);
}
*/
int** generateMatrix(int n);
int main()
{
int n;
printf("请输入正方形矩阵的阶数 n : ");
scanf_s("%d", &n);
//分配一个二维数组
int** returnArry = (int**)malloc(sizeof(int*) * n);//先分配一个一维的
for (int i = 0; i < n; i++) {
returnArry[i] = (int*)malloc(sizeof(int) * n);//再分配二维
}
returnArry = generateMatrix(n);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf("%6d", returnArry[i][j]);
}
printf("\n\n");
}
free(returnArry);
system("pause");
return 0;
}
int** generateMatrix(int n) {
//分配一个二维数组,作为返回值
int** returnArry = (int**)malloc(sizeof(int*) * n);
for (int i = 0; i < n; i++) {
returnArry[i] = (int*)malloc(sizeof(int) * n);
}
int startX = 0, startY = 0;
int offset = 1;
int count = 1;
int i, j;
for (int k = 0; k < n / 2; k++) { //转一圈,正方形矩阵左右都会减少一列,宽度-2,总宽为n,故循环n/2次
for (i = startX; i < n - offset; i++) { //保证行不变,遍历列
returnArry[startY][i] = count++;
}
for (j = startY; j < n - offset; j++) { //保证列不变,遍历行
returnArry[j][i] = count++;
}
for (; i > startX; i--) { //保证行不变,遍历列(此时的i,j都已经最大,到达矩阵最右下角的位置
returnArry[j][i] = count++;
}
for (; j > startY; j--) { //保证列不变,遍历行
returnArry[j][i] = count++;
} //上一个循环的变量是下一个循环中行或列的不变量,衔接
startX++;
startY++;
offset++;
}
if (n % 2 == 1) { //如果n为单数需要将最后(最中间的元素加到数组中去)
returnArry[startX][startY] = count;
}
return returnArry;
}
给出运行结果图:


IDE:visual studio 2019
同样给出letcode题解代码如下(自己的题解):
int** generateMatrix(int n, int* returnSize, int** returnColumnSizes) {
*returnSize = n; //二维数组的元素个数
*returnColumnSizes = (int*)malloc(sizeof(int) * n); //多少列
int** returnArry = (int**)malloc(sizeof(int*) * n); //返回的二维数组
for (int i = 0; i < n; i++) {
returnArry[i] = (int*)malloc(sizeof(int) * n);
(*returnColumnSizes)[i] = n;
}
int startX = 0, startY = 0;
int offset = 1;
int count = 1;
int i, j;
for (int k = 0; k < n / 2; k++) {
for (i = startX; i < n - offset; i++) { //保证行不变,遍历列
returnArry[startY][i] = count++;
}
for (j = startY; j < n - offset; j++) { //保证列不变,遍历行
returnArry[j][i] = count++;
}
for (; i > startX; i--) { //保证行不变,遍历列(此时的i,j都已经最大,到达矩阵最右下角的位置
returnArry[j][i] = count++;
}
for (; j > startY; j--) { //保证列不变,遍历行
returnArry[j][i] = count++;
} //上一个循环的变量是下一个循环中行或列的不变量,衔接
startX++;
startY++;
offset++;
}
if (n % 2 == 1) {
returnArry[startX][startY] = count;
}
return returnArry;
}
总结
题目本身不难,但是就是一写就废,一顿Debug,不过前期也正常,一定要坚持,多写写,多练练,自然就熟能生巧,思路也很更清晰,思维也会更活跃,希望对大家有帮助,欢迎大家提问或指正😁😁😁
本文介绍了如何使用C语言生成螺旋排列的正方形矩阵。作者分享了从问题理解、解题思路到代码实现的全过程,包括二维数组的动态内存分配和遍历规则。通过示例代码展示了具体实现,并提供了运行结果。强调了二维数组分配的注意事项,以及做算法题时画图辅助理解的重要性。

2811

被折叠的 条评论
为什么被折叠?



