螺旋矩阵 II

43 阅读2分钟

螺旋矩阵 II

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

  • 思路
    看到这道题目,可能开始没有思路,但是仔细想一想具体的过程其实就是模拟过程,模拟着画出一个螺旋矩阵即可。而在画螺旋矩阵是会遇到边界的问题。在处理边界时,一定要坚持循环不变原则,和二分法中处理边界时类似。我们这里可以采用左闭右开的原则,或是左开右闭的原则。但是不能是左闭右闭,因为这样会导致边界重复填充。
    使用左闭右开原则模拟顺时针画矩阵的过程:
  • 填充上行从左到右
  • 填充右列从上到下
  • 填充下行从右到左
  • 填充左行从下到上
    这里还会遇到一个问题,当n是奇数时,最后需要单独填充最中间的一个格子。
  • 代码如下:
class Solution {
    public int[][] generateMatrix(int n) {
        int[][] res = new int[n][n];
        int startx = 0,starty = 0; // 定义每循环一圈的起始位置
        int loop = n / 2; // 循环多少圈,例如n = 3是奇数,那么loop = 1 ,只循环一圈,矩阵最中间的位置需要单独填充
        int mid = n / 2; // 矩阵中间的位置,例如:n为3,中间的位置为(1,1),n为5,中间的位置为(2,2)
        int count = 1; // 用来给矩阵中的每一个空格赋值
        int offset = 1; // 需要控制每一条边遍历的长度,每次循环右边界收缩一位
        int i,j;
        while (loop != 0){
            loop --;
            i = startx;
            j = starty;

            // 下面开始的四个for循环就是模拟转了一圈
            // 模拟填充上行从左到右(左闭右开)
            for (j = starty; j < n - offset; j ++) {
                res[startx][j] = count++;
            }
            // 模拟填充右列从上到下
            for (i = startx; i < n - offset; i ++) {
                res[i][j] = count++;
            }
            // 模拟填充下行从右向左
            for (; j > starty ; j--) {
                res[i][j] = count++;
            }
            // 模拟填充左列从下到上
            for (;i > startx;i --){
                res[i][j] = count++;
            }

            // 第二圈开始的时候,起始位置要各自加1,例如:第一圈的起始位置是(0,0),第二圈的起始位置就是(1,1)。
            startx ++;
            starty ++;

            // offset控制每一圈中买一条边遍历的长度
            offset --;
        }

        // 如果n为奇数,需要单独给矩阵最中间的位置填充
        if (n % 2 == 1){
            res[mid][mid] = count;
        }
        return res;
    }
}