⚡『LeetCode-Offer』一图看懂 LeetCode59. 螺旋矩阵 II

3,308 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

📃 题目描述

题目链接:59. 螺旋矩阵 II - 力扣(LeetCode) (leetcode-cn.com)

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

示例 1:

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

示例 2:

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

🔔 解题思路

本题没有什么算法思想可言,主要思路就是按照螺旋顺序对数组进行循环赋值就行了,其难点就在于边界的处理。

这种看起来没啥套路,直接按照过程进行逐步求解的思想,也成为 “模拟法

顺时针螺旋的四个方向:

  • 从左到右
  • 从上到下
  • 从右到左
  • 从下到上

具体过程咱也不整文字了,直接看图就明白了:

 class Solution {
     public int[][] generateMatrix(int n) {
         int[][] res = new int[n][n];
 ​
         // 最左列
         int left = 0;
         // 最右列
         int right = n - 1;
         // 最上行
         int up = 0;
         // 最下行
         int bottom = n - 1;
 ​
         // 当前填充的数
         int curNum = 1;
 ​
         // 循环 n/2 次
         while (curNum <= n * n) {
             // 左 -> 右 (触碰到右边界则转为向下遍历)
             for (int j = left; j <= right; j++) {
                 res[up][j] = curNum++;
             }
             up++;
 ​
             // 上 -> 下 (触碰到下边界则转为向左遍历)
             for (int j = up; j <= bottom; j++) {
                 res[j][right] = curNum++;
             }
             right--;
 ​
             // 右 -> 左 (触碰到左边界则转为向上遍历)
             for (int j = right; j >= left; j--) {
                 res[bottom][j] = curNum++;
             }
             bottom--;
 ​
             // 下 -> 上 (触碰到上边界则转为向右遍历)
             for (int j = bottom; j >= up; j--) {
                 res[j][left] = curNum++;
             }
             left++;
         }
 ​
         return res;
     }
 }

这个解法也直接适用于这道题,基本上一模一样:54. 螺旋矩阵 - 力扣(LeetCode) (leetcode-cn.com)

还有一种写起来比较简单的解法:

 class Solution {
     public int[][] generateMatrix(int n) {
         int[][] res = new int[n][n];
 ​
         // 四个方向: 右下左上
         int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
         // 指定哪个方向
         int directionIndex = 0;
 ​
         // 当前填充的数
         int curNum = 1;
         // 最后一个数
         int maxNum = n * n;
 ​
         // 行数
         int row = 0;
         // 列数
         int column = 0;
 ​
         while (curNum <= maxNum) {
             // 填充一个数
             res[row][column] = curNum;
             curNum ++;
 ​
             // 若下一步的位置超出矩阵边界,或者是已经被赋过值的位置,则进入下一个方向
             int nextRow = row + directions[directionIndex][0];
             int nextColumn = column + directions[directionIndex][1];
             if (nextRow < 0 || nextRow >= n || nextColumn < 0 || nextColumn >= n || res[nextRow][nextColumn] != 0) {
                 directionIndex = (directionIndex + 1) % 4;
             }
 ​
             // 进入下一个位置
             row = row + directions[directionIndex][0];
             column = column + directions[directionIndex][1];
         }
 ​
         return res;
     }
 }

💥 复杂度分析

  • 空间复杂度:O(N^2)
  • 时间复杂度:O(N^2)

如果小伙伴们和我一样总是犯愁刷题没有顺序和体系,最终导致半途而废的话,可以看这里哦:LeetCode-Offer: LeetCode + 剑指 Offer = 💰,博主目前东南大学硕士在读,也在准备秋招,大伙儿可以来这里一起每天刷题打卡呀~

我的 公众号『 飞天小牛肉 』,专注分享计算机基础(数据结构 + 算法 + 计算机网络 + 数据库 + 操作系统 + Linux)、Java 技术栈等相关原创技术好文。关注公众号第一时间获取文章更新,后台回复 300 即可免费获取极客大学出品的 Java 面试 300 题,回复 Echo 免费领取 star 1k+ 社区项目的配套教程