LeetCode 59 Matriz Espiral II js

Haga clic en el enlace de la pregunta

tema:

Dado un número entero positivo  n , genere una matriz cuadrada que contenga  1 todos  n2 los elementos (n✖️n matriz cuadrada), y los elementos se organizan en espiral en el  n x n sentido  de las agujas del reloj matrix .

Ejemplo:

Entrada n=3, salida:

Como se muestra en la imagen de arriba, hay un total de cuatro bordes que deben rellenarse. Deben rellenarse en el sentido de las agujas del reloj, siguiendo la regla izquierda-cerrada-derecha-abierta. La última posición se pasa al siguiente borde, que son:

Arriba ---> de izquierda a derecha

Fila derecha ---> de arriba a abajo

Abajo--->de derecha a izquierda

Fila izquierda ---> de abajo hacia arriba

Después de cada ronda de recorrido, la posición inicial de la siguiente ronda de recorrido será +1 y la posición límite final también será -1.

Si n es un número impar, aún necesitamos procesar el valor intermedio. Cuando n es un número par, se completará después del recorrido. Los números impares perderán la posición media y deberán completarse manualmente.

Después de aclarar todo el proceso, se implementa el código:

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

En comparación con el método de dicotomía, esta pregunta prueba el control de las invariantes del bucle. Sólo insistiendo en la definición del intervalo en el bucle podemos comprender mejor los detalles del bucle. 

​​​​​​​Código Capriccio Enlace

Supongo que te gusta

Origin blog.csdn.net/Suk__/article/details/128694975
Recomendado
Clasificación