思路
模拟顺时针画矩阵的过程:
- 填充上行从左到右
- 填充右列从上到下
- 填充下行从右到左
- 填充左列从下到上
由外向内一圈一圈这么画下去。
- 难点:边界值(拐角处)的判断容易混淆
- 方法:每一次遍历都遵循同一个原则:左闭右开 || 左开右闭
题目
解题步骤
- 初始化一些变量,包括起始坐标(starX和starY),螺旋圈数(loop),中间位置(mid),拐角的边界值(offset)和填充元素(count)。
- 创建一个n x n的二维数组(res)来存储结果。
- 使用while循环来遍历每个圈。在每个圈中,我们按照四个方向进行遍历:从左到右,从上到下,从右到左,从下到上。在每个方向上,我们使用count变量来填充元素,并在每次填充后递增count。
- 在遍历完一圈后,我们需要更新起始坐标和边界值,以便处理下一个圈。
- 如果n是奇数,我们需要单独处理最中间的元素。
- 最后,返回填充好的二维数组。
JS示例代码
var generateMatrix = function (n) {
let starX = starY = 0
let loop = Math.floor(n / 2)//螺旋圈数
let mid = Math.floor(n / 2)//为n为奇数时中间位置
let offset = 1//拐角的边界值
let count = 1//填充元素
let res = new Array(n).fill(0).map(() => new Array(n).fill(0))//n*n矩阵二维数组
while (loop--) {
let row = starX//行
let col = starY//列
//以下遍历都遵循左闭右开的规则,即只包含每行(列)初始拐角(第一个元素),不包含末尾拐角(最后一个元素)
// 上行从左到右遍历,列变行不变
// 此时行列坐标都在左上角,需要递增
for (; col < n - offset; col++) {
res[row][col] = count
count++//每次填充完 数值递增
}
// 右行从上到下遍历,行变列不变
for (; row < n - offset; row++) {
res[row][col] = count
count++
}
// 下行从右到左遍历,列变行不变
// 此时行列坐标都在右下角,需要递减
for (; col > starY; col--) {
res[row][col] = count
count++
}
// 左行从下到上遍历,行变列不变
for (; row > starX; row--) {
res[row][col] = count
count++
}
//每遍历完一圈,会开始遍历更里面的一圈,圈变小了,所以需要进行以下操作
//初始坐标递增
starX++
starY++
//边界值递增
offset++
}
//遍历完圈数后,如果n为奇数,最中间存在一个元素,直接赋值
if (n % 2 == 1) {
res[mid][mid] = count
}
return res
};