数组篇--螺旋矩阵

210 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情

1.题目一

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]]


思路

如果要写出正确的二分法一定要坚持循环不变量原则

而求解本题依然是要坚持循环不变量原则。

模拟顺时针画矩阵的过程:

  • 填充上行从左到右
  • 填充右列从上到下
  • 填充下行从右到左
  • 填充左列从下到上

由外向内一圈一圈这么画下去。

可以发现这里的边界条件非常多,在一个循环中,如此多的边界条件,如果不按照固定规则来遍历,那就是非常复杂

这里一圈下来,我们要画每四条边,这四条边怎么画,每画一条边都要坚持一致的左闭右开,或者左开又闭的原则,这样这一圈才能按照统一的规则画下来。

生成一个 n×n 空矩阵 mat,随后模拟整个向内环绕的填入过程: 定义当前左右上下边界 l,r,t,b,初始值 num = 1,迭代终止值 tar = n * n; 当 num <= tar 时,始终按照 从左到右 从上到下 从右到左 从下到上 填入顺序循环,每次填入后: 执行 num += 1:得到下一个需要填入的数字; 更新边界:例如从左到右填完后,上边界 t += 1,相当于上边界向内缩 1。 使用num <= tar而不是l < r || t < b作为迭代条件,是为了解决当n为奇数时,矩阵中心数字无法在迭代过程中被填充的问题。


代码

var generateMatrix = function (n) {
    let left = 0, top = 0;
    let right = n-1, bot = n-1;
    let res = [];
    for (let k = 0; k < n; k++) {
        res.push([]);
    }
    let num = 1
    while (num <= n*n) {
        for (let i = left; i <= right; i++) {
            res[top][i] = num;
            num++
        }
        top++
        for (let i = top; i <=bot; i++) {
            res[i][right] = num;
            num++
            
        }
        
        right--
        
        for (let i = right; i >= left; i--) {
            res[bot][i] = num
            num++
        }
        bot--
        
        for (let i = bot; i >= top; i--) {
            res[i][left] = num
            num++
        }
        left++
    }
    return res
};