LeetCode 59 螺旋矩阵II js

1 篇文章 0 订阅

力扣题目链接

题目:

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

示例:

输入n=3, 输出:

根据上图所示, 一共有四条边需要填充,要按照顺时针进行,遵循左闭右开规则,最后一个位置交给下一条边处理,分别是:

上行--->从左到右

右行--->从上到下

下行--->从右到左

左行--->从下到上

每遍历完一圈,下一圈遍历的起始位置就要+1,结束的边界位置也要-1

如果n为奇数 我们还要处理中间值 n为偶数时遍历完就填充好了 奇数会漏掉中间的位置 需要手动填充

捋清楚整个过程后,代码实现:

/**
     * @description 生成n*n螺旋矩阵
     * @param {number} n 要生成矩阵的边长
     * @return {number[][]}
     * */
    function generateMatrix(n) {
      let startX = (startY = 0) // 每圈遍历的起始位置
      let loop = n >> 1 // 遍历的圈数 只需要遍历Math.floor(n/2)圈
      let mid = n >> 1 // 中间位置索引 n为奇数时需要单独填充中间值 位置(x,y)为(Math.floor(n/2), Math.floor(n/2))
      let count = 1 // 填充的值 每填充一次++
      let offset = 1 // 每遍历一圈边界缩小一位
      const result = new Array(n).fill(0).map((e) => new Array(n).fill(0)) // 初始化一个n*n的二维数组做为矩阵
      // 循环的条件就是圈数 遍历一圈就-- 为0时false结束遍历
      while (loop--) {
        // 每圈开始初始化行和列变量
        let col = startX
        let row = startY
        // 左闭右开原则 每条边的最后一个位置交给下一条边的第一个填充
        // 从上行开始 从左到右遍历<n-offset次
        for (; col < n - offset; col++) {
          result[row][col] = count++
        }
        // 右行从上到下遍历<n-offset次 此时col到了右边最后一个且在这个循环恒定不变
        for (; row < n - offset; row++) {
          result[row][col] = count++ // 填充第col列每一行右行的值
        }
        // 下行从右到左 所以col要--来控制填充顺序 直到col===startX停止 当遍历到startX则到了这一圈这条边要填充的最后一个
        for (; col > startX; col--) {
          result[row][col] = count++ // 此时的row为最后一行且在这个循环恒定不变
        }
        // 左行从下到上 row要--来控制从下往上填充 直到row===startY停止 当遍历到startY则到了这一圈这条边要填充的最后一个
        for (; row > startY; row--) {
          result[row][col] = count++
        }
        // 填充完一圈将下一圈填充的起始位置+1 边界值也要+1
        startX++
        startY++
        offset++
      }
      // 圈都填充完后 判断矩阵是否有中间位置 边长为偶数的矩阵没有中间值 如果n是奇数则有中间值 手动填充
      if ((n & 1) === 1) {
        result[mid][mid] = count
      }
      return result
    }

这道题相比二分法更加考验了对循环不变量的控制,只有在循环中坚持对区间的定义,才能更好的把握循环里的各个细节 

​​​​​​​代码随想录链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值