循环矩阵-59

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第10天,点击查看活动详情

螺旋矩阵 II

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

解题思路

模拟顺时针画矩阵的过程:

  1. 从左到右填充上行;
  2. 从上到下补充右列;
  3. 从右到左补充下列;
  4. 从下到上补充左列

由外向内画圈,一圈一圈地画下去。

这道题的难点在于每层循环的边界条件,对于这种多层循环条件,很容易写着写着,边界 就变了,导致程序难以正常执行。

所以在编写代码之前就要确定循环的边界条件,在这个大前提下,进行每个循环的逻辑编写。

数组遍历,下标与长度差值为1,所以确定所有边界:左闭右开

边界的确定在于

  1. n 与循环周期的关系 即循环条件 cycle? cycle = n / 2
  2. 考虑 offset的初始值取多少?offset = 1, 比如 n = 3, 第二例的最后一个值是不需要第一行遍历赋值的,而是由最后一列赋值;同理 最后一列最后一行同样不由最后一列赋值,而是由最后一行赋值,所以 offset = 1
  3. 找出 每层长度 与 索引 和 整数 n 以及 offset 的规律 length = n + starty/startx - offset

流程图

spiralMatrixII-.png

代码实现

public class Solution {

    public int[][] generateMatrix(int n) {
        int[][] nums = new int[n][n];
        // 确定循环周期
        int cycle = n/2;
        // 设置起始下标
        int startx = 0;
        int starty = 0;
        int i;
        int j;
        // 设置每个周期循环时控制每层遍历长度
        // 因为是一个正方形顺时针填充,即上下左右,所以每层遍历
        // 不需要遍历到最后一个值,因为上层最后一个值时右边第一个值的开始
        // 右边最后一个值是下层最后一个值,而下层最开始的值是左边第一个值的开始
        // 所以 offset 初始值设置为 1
        int offset = 1;
        // 正方形矩阵最小值为1
        int count = 1;

        // 开始周期循环画矩阵
        while(cycle-- > 0){
            i = startx;
            j = starty;
            // 上边从左到右
            for(; j<n+starty-offset; j++){
                nums[i][j] = count++;
            }
            // 左边从上到下
            for(; i<n+startx-offset; i++){
                nums[i][j] = count++;
            }
            // 下边从右到左
            for(; j>starty; j--){
                nums[i][j] = count++;
            }
            // 左边从下到上
            for(; i>startx; i--){
                nums[i][j] = count++;
            }

            // 每画完一层 startx starty 下标自增1
            startx++;
            starty++;

            // 偏移量 +2 即画一层,每层长度遍历就要 -2
            // 上下左右都有值,中间的长度可不就减 2 了
            offset += 2;
        }

        // 确定中间值,如果 n 为奇数
        if(n%2!= 0){
            // 设置中间下标索引,当 n 为奇数时,
            int mid = n/2;
            nums[mid][mid] = n * n;
        }

        return nums;
    }
}
复制代码

猜你喜欢

转载自juejin.im/post/7084988381037821966