LeetCode 59 Spiral Matrix II (Tag:Array Difficulty:Meduim)

201 阅读2分钟

这是我参与8月更文挑战的第16天,活动详情查看:8月更文挑战

前言

关于 LeetCode 数组类型题目的相关解法,可见LeetCode 数组类型题目做前必看,分类别解法总结了题目,可以用来单项提高。觉得有帮助的话,记得多多点赞关注哦,感谢!

题目描述

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

示例 1:
image.png
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]

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

链接:leetcode-cn.com/problems/sp…

题解

这道题目和leetcode 54是相似的, 不同的是 54 题要求顺时针遍历矩阵, 而本题要求的是顺时针填充数组. 其实, 从方法上来讲两者没有差别. 主要有以下几个要点:

  1. 定义方向数组. 因为是顺时针遍历, 所以一共有四个方向, 从左到右, 从上到下, 从右到左, 从下到上, 相应的方向数组为 [[0, 1], [1, 0], [0, -1], [-1, 0]], 同时用一个变量 dirIndex 表示现在的前进方向.

  2. 定义上下左右四个边界, 这四个边界的作用是防止顺时针遍历的时候越界, 当在一个方向上前进到边界时, 要改变前进的方向, 即改变 dirIndex 的值, dirIndex 加 1, 同时要缩短相应的边界, 比如到达了右边界, 那么要把上边界向下缩短.

  3. 用变量 now 来表示填充的数字, 顺时针遍历的条件是 now <= n * n

具体代码实现见如下代码, 可以根据代码来对照上面的三个重要点, 体会这几个变量的意义.

时间复杂度 O(n²), 空间复杂度 O(1)

/**
 * @param {number} n
 * @return {number[][]}
 */
var generateMatrix = function(n) {
    let dir = [[0, 1], [1, 0], [0, -1], [-1, 0]]
    let dirIndex = 0
    let res = Array.from({length: n}, () => (new Array(n)))
    let now = 1
    let top = left = 0
    let bottom = right = n - 1
    let x = y = 0
    while(now <= n * n) {
      res[x][y] = now
      if (y === right && dirIndex === 0) {
        ++top
        ++dirIndex
      } else if (x === bottom && dirIndex === 1) {
        --right
        ++dirIndex
      } else if (y === left && dirIndex === 2) {
        --bottom
        ++dirIndex
      } else if (x === top && dirIndex === 3) {
        ++left
        ++dirIndex
      }
      dirIndex %= 4
      x += dir[dirIndex][0]
      y += dir[dirIndex][1]
      ++now
    }
 return res
};