LeetCode 59 Spiral Matrix II js

Click on the question link

topic:

Given a positive integer  n , generate a square matrix containing  1 all  n2 elements (n✖️n square matrix), and the elements are spirally arranged in clockwise  n x n order  matrix .

Example:

Input n=3, output:

As shown in the picture above, there are a total of four edges that need to be filled. They should be filled in clockwise, following the left-closed-right-open rule. The last position is handed over to the next edge, which are:

Up ---> from left to right

Right row ---> from top to bottom

Down--->right to left

Left row ---> from bottom to top

After each round of traversal, the starting position of the next round of traversal will be +1, and the end boundary position will also be -1.

If n is an odd number, we still need to process the intermediate value. When n is an even number, it will be filled in after traversing. Odd numbers will miss the middle position and need to be filled manually.

After clarifying the whole process, the code is implemented:

/**
     * @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
    }

Compared with the dichotomy method, this question tests the control of loop invariants. Only by insisting on the definition of the interval in the loop can we better grasp the details of the loop. 

​​​​​​​Code Capriccio Link

Guess you like

Origin blog.csdn.net/Suk__/article/details/128694975