59.螺旋矩阵II

😵 59.螺旋矩阵II

给你一个正整数 n ,生成一个包含 1n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix

示例

示例 1:

img
1
2
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]

示例 2:

1
2
输入:n = 1
输出:[[1]]

思路

基本思想

为了模拟螺旋的情况,一圈循环当成一个整体,一圈一圈的向内收缩,并且每一圈可以分割成等长的四个长方形,分割情况如下图所示:

image-20230721204948603

其中每一个颜色代表一个分割结果,创建螺旋数组时,需要选择一个起点,每一圈的起点都不同,并且每个螺旋数组旋转的圈数也不同,所以需要定义很多变量:

1
2
3
4
5
6
7
8
int startx=0;//起点的横坐标
int starty=0;//起点的纵坐标
//由于每一圈的地点都在主对角线上,所以一个start就可以记录起点的位置
//int start=0;//起点的坐标
int loop=n/2;//螺旋数组遍历多少圈
int mid=n/2;//螺旋数组的中心点
int num=1;//螺旋数组中每个位置的值
int offset=1;//定义每一圈分割之后,长方形的长度

需要注意的是螺旋数组遍历多少圈,这个需要理解,如果给定n=3,那么只需要遍历一圈,如果给定n=5,那么需要遍历两圈

其中offset代表每一圈分割成四个长方体之后,长方体的长度,每遍历一圈,长方体的长度就会减小一,理解了这些就是纯代码模拟了

执行流程

  1. 从左到右填充第一个长方形,此时行不变
  2. 从上到下填充第二个长方形,此时列不变
  3. 从右到左填充第三个长方形,此时行不变
  4. 从下到上填充第四个长方形,此时列不变
  5. 一圈结束之后,更新下一圈的起点,并且下一圈的长方形的长度也需要更新

注意for循环中的i,j不能使用临时变量,要在for循环外定义,方便记住此时的遍历位置

代码

根据以上分析,得出以下代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class Solution {
public:
    //主要是靠代码模拟旋转
    vector<vector<int>> generateMatrix(int n) {
        int start=0;//起点的坐标
        int loop=n/2;//螺旋数组遍历多少圈
        int mid=n/2;//螺旋数组的中心点
        int num=1;//螺旋数组中每个位置的值
        int offset=1;//定义每一圈分割之后,长方形的长度
        int i,j;
        vector<vector<int>>res (n,vector<int>(n,0));
        while(loop--){
            //1. 从左到右填充,行不变
            for(i=start;i<n-offset;++i){
                res[start][i]=num++;
            }
            //2. 从上到下填充,列不变
            for(j=start;j<n-offset;++j){
                res[j][i]=num++;
            }
            //3. 从右到左填充,行不变
            for(;i>start;--i){
                res[j][i]=num++;
            }
            //4. 从下到上填充,列不变
            for(;j>start;--j){
                res[j][i]=num++;
            }
            //更新下一圈的起点以及下一圈中长方形的长度
            start++;
            offset++;
        }
        //如果给定的n是奇数,那么中心点单独处理
        if(n%2==1){
            res[mid][mid]=num;
        }
        return res;
    }
};

总结

主要是将创建螺旋数组的步骤分成一圈一圈的,每一圈分割成四个大小一样的长方形,并且记录每一圈的起点和每一圈中长方形的长度,以此将问题分割,关键点总结为三个:

  1. 分割成以圈为单位
  2. 一圈分割成四个大小一样的长方形
  3. 记录每一圈的起点和长方形的长度