算法--数组--螺旋矩阵 II

120 阅读3分钟

算法--数组--螺旋矩阵 II

力扣题目链接

给定一个正整数  n,生成一个包含 1 到  n^2  所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。

示例:

输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]

1 解答

先写再看噢~

解答

这个讲得很详细👉代码随想录

1.1 思路

// 思路比较简单,两个指针,一个指针走到底,换另一个走,j++, i++, j--, i--
// 但是用 while 循环,每次都会从第一个 if 开始判断,就得控制走到对的if判断里,用 n=3,4,5,的试,往往是这个条件加上,这一圈符合了,下一圈又走不对了
// 尝试中👇
const generateMatrix = function (n) {
  const array = new Array(n).fill(0).map(() => new Array(n).fill(0));

  let i = 0;
  let j = 0;
  let k = 1;

  while (k <= n * n) {
    array[i][j] = k;
    k++;

    if (j < n - 1 && i < n / 2) {
      // 上行从左到右
      if (!array[i][j + 1]) {
        j++;
      } else if (i > 0) {
        i++;
      }
    } else if (i < n - 1 && j > n / 2) {
      // 右列从上到下
      if (!array[i + 1][j]) {
        i++;
      } else if (j > 0) {
        j--;
      }
    } else if (j > 0 && i >= n / 2) {
      // 下行从右到左
      if (!array[i][j - 1]) {
        j--;
      } else if (i < n - 1) {
        i--;
      }
    } else if (i > 0 && j <= n / 2) {
      // 左列从下到上
      if (!array[i - 1][j]) {
        i--;
      } else if (j < n - 1) {
        j++;
      }
    }
  }

  return array;
};

1.2 优化

自己控制起点终点

const generateMatrix = function (n) {
  const array = new Array(n).fill(0).map(() => new Array(n).fill(0));

  let i = 0;
  let j = 0;
  let k = 1; // 值

  let loop = 0; // 圈数

  while (k <= n * n) {
    let startI = loop; // 每圈i的最小值
    let endI = n - 1 - loop; // 每圈i的最大值
    let startJ = loop; // 每圈j的最小值
    let endJ = n - 1 - loop; // 每圈j的最大值

    if (0 + loop === n - 1 - loop) {
      array[loop][loop] = k++; // 起点等于终点,最中间的赋值
      break;
    } else if (0 + loop > n - 1 - loop) {
      break;
    }

    // 上行从左到右(左闭右开)
    i = startI;
    for (j = startJ; j <= endJ - 1; j++) {
      array[i][j] = k++;
    }

    // 右列从上到下(左闭右开)
    j = endJ;
    for (i = startI; i <= endI - 1; i++) {
      array[i][j] = k++;
    }

    // 下行从右到左(左闭右开)
    i = endI;
    for (j = endJ; j >= startJ + 1; j--) {
      array[i][j] = k++;
    }

    // 左列从下到上(左闭右开)
    j = startJ;
    for (i = endI; i >= startI + 1; i--) {
      array[i][j] = k++;
    }

    loop++; // 圈数增加
  }

  return array;
};

时间复杂度 o(n^2) 空间复杂度 o(n^2)

1.3 优化

/**
 * @param {number} n
 * @return {number[][]}
 */
var generateMatrix = function (n) {
  let startX = (startY = 0); // 起始位置
  let loop = Math.floor(n / 2); // 旋转圈数
  let mid = Math.floor(n / 2); // 中间位置
  let offset = 1; // 控制每一层填充元素个数
  let count = 1; // 更新填充数字
  let res = new Array(n).fill(0).map(() => new Array(n).fill(0));

  while (loop--) {
    let row = startX,
      col = startY;
    // 上行从左到右(左闭右开)
    for (; col < startY + n - offset; col++) {
      res[row][col] = count++;
    }
    // 右列从上到下(左闭右开)
    for (; row < startX + n - offset; row++) {
      res[row][col] = count++;
    }
    // 下行从右到左(左闭右开)
    for (; col > startY; col--) {
      res[row][col] = count++;
    }
    // 左列做下到上(左闭右开)
    for (; row > startX; row--) {
      res[row][col] = count++;
    }

    // 更新起始位置
    startX++;
    startY++;

    // 更新offset
    offset += 2;
  }
  // 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
  if (n % 2 === 1) {
    res[mid][mid] = count;
  }
  return res;
};