这是我参与8月更文挑战的第16天,活动详情查看:8月更文挑战
前言
关于 LeetCode 数组类型题目的相关解法,可见LeetCode 数组类型题目做前必看,分类别解法总结了题目,可以用来单项提高。觉得有帮助的话,记得多多点赞关注哦,感谢!
题目描述
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
示例 1:
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
示例 2:
输入:n = 1
输出:[[1]]
链接:leetcode-cn.com/problems/sp…
题解
这道题目和leetcode 54是相似的, 不同的是 54 题要求顺时针遍历矩阵, 而本题要求的是顺时针填充数组. 其实, 从方法上来讲两者没有差别. 主要有以下几个要点:
-
定义方向数组. 因为是顺时针遍历, 所以一共有四个方向, 从左到右, 从上到下, 从右到左, 从下到上, 相应的方向数组为 [[0, 1], [1, 0], [0, -1], [-1, 0]], 同时用一个变量 dirIndex 表示现在的前进方向.
-
定义上下左右四个边界, 这四个边界的作用是防止顺时针遍历的时候越界, 当在一个方向上前进到边界时, 要改变前进的方向, 即改变 dirIndex 的值, dirIndex 加 1, 同时要缩短相应的边界, 比如到达了右边界, 那么要把上边界向下缩短.
-
用变量 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
};