携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情
59. 螺旋矩阵 II
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
「示例1:」
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
「示例2:」
输入:n = 1
输出:[[1]]
「提示:」
1 <= n <= 20
解题思路
// 第一种
构建 n * n 的矩阵
确定矩阵的四个边界,它是初始遍历的边界。
按 上 右 下 左,一层层向内,遍历矩阵填格子
每遍历一个格子,填上对应的 num,num 自增
直到 num > n*n ,遍历结束
// 第二种
r 生成 n * n 二维数组,r[y][x]表示第 y 行第 x 列,i 从 1 到 n的n次方 递增
按 →↓←↑ 顺序,碰撞 到边界 转向
→ 列 x++。↓ 行 y++。←列 x--。↑ 行 y--。填完 i 返回 r 即可
// 第三种
感觉好久之前有过这种一模一样的题,也是螺旋数。
①:建立矩阵,因为输出是二维数组
new Array(n).fill(0).map(() => new Array(n).fill(0))
②:有上下左右四个方向,我们就先找边界条件,left <= right && top <= bottom
其中 left = 0, right = n - 1, top = 0, bottom = n - 1 分别代表四个边界值
③:因为螺旋数是依次递增的 所以在每次按顺序循环时都会 +1,
④:四个方向:
向右: 行数固定,列数依次+1(边界值内)
向下: 列数固定,行数依次+1(边界值内)
向左: 行数固定,列数依次-1(边界值内)
向上: 列数固定,行数依次-1(边界值内)
代码实现
// 第一种
var generateMatrix = function (n) {
const matrix = new Array(n);
for (let i = 0; i < n; i++) {
matrix[i] = new Array(n);
}
let num = 1;
let left = 0, right = n - 1, top = 0, bottom = n - 1;
while (num <= n * n) {
for (let i = left; i <= right; i++) {
matrix[top][i] = num
num++
}
top++;
for (let i = top; i <= bottom; i++) {
matrix[i][right] = num
num++;
}
right--;
for (let i = right; i >= left; i--) {
matrix[bottom][i] = num
num++;
}
bottom--;
for (let i = bottom; i >= top; i--) {
matrix[i][left] = num
num++;
}
left++;
}
return matrix;
};
// 第二种
var generateMatrix = function(n) {
var b = [0, n - 1, 0, n - 1], x = 0, y = 0, i = 0, d = '→', r = new Array(n).fill(0).map(_=>new Array(n).fill(0))
while (i++ < Math.pow(n, 2)) {
d === '→' && (r[y][x++] = i, x === b[1] && (d = '↓', ++b[2])) ||
d === '↓' && (r[y++][x] = i, y === b[3] && (d = '←', b[1]--)) ||
d === '←' && (r[y][x--] = i, x === b[0] && (d = '↑', b[3]--)) ||
d === '↑' && (r[y--][x] = i, y === b[2] && (d = '→', ++b[0]))
}
return r
};
// 第三种
/**
* @param {number} n
* @return {number[][]}
*/
var generateMatrix = function(n) {
let res = new Array(n).fill(0).map(() => new Array(n).fill(0))
let cur = 1, left = 0, right = n - 1, top = 0, bottom = n - 1
while(left <= right && top <= bottom) {
for (let j = left; j <= right; j++) {
res[top][j] = cur
cur++
}
top++
for (let i = top; i <= bottom; i++) {
res[i][right] = cur
cur++
}
right--
for (let j = right; j >= left; j--) {
res[bottom][j] = cur
cur++
}
bottom--
for (let i = bottom; i >= top; i--) {
res[i][left] = cur
cur++
}
left++
}
return res
};
如果你对这道题目还有疑问的话,可以在评论区进行留言;