每日算法Day31 -- 填充螺旋矩阵

211 阅读1分钟

题目描述:

image.png

大致思路:

从外圈 四条边开始填充, 按照 上、 右、 下、 左的顺序依次填充, 此时对应的值为按顺序递增的, 外圈填充完毕后, 再从第二层开始, 进行递归, 递归结束条件为:

  1. 第二层递归的长度为上次的长度 -2, 当本次长度为2时, 则没有左边了, 直接结束。
  2. 当本次长度为1时, 递归结束条件为最后的开始值等于 n * n时, 结束递归。

本道题在逻辑上并不复杂, 复杂的是一些边界情况以及后续递归填充值对应的位置, 需要细心。

代码如下:

function generateMatrix(n: number): number[][] {
  const res: number[][] = [];

  for (let i = 0; i < n; ++i) {
    res[i] = [];
  }

  const sum = n * n;
  const fn = (start: number, length: number, count: number) => {
    //递归开始
    if (start === sum) {
      res[Math.floor(n / 2)][Math.floor(n / 2)] = sum;
      return;
    }
    //生成数组的方法, 在此方法中给 start递增
    const generateArr = (len: number) => {
      const res: number[] = [];
      for (let i = 0; i < len; ++i) {
        res.push(start++);
      }
      return res;
    };

    //依次填充方形 四条边
    //top:
    generateArr(length).forEach((num, index) => {
      res[count][count + index] = num;
    });
    //right:
    generateArr(length - 1).forEach((num, index) => {
      res[index + 1 + count][n - 1 - count] = num;
    });

    //bottom:
    generateArr(length - 1).forEach((num, index) => {
      res[n - 1 - count][n - count - 2 - index] = num;
    });

    //递归开始, 最后不需要填充左侧
    if (length === 2) {
      return;
    }
    //left
    generateArr(length - 2).forEach((num, index) => {
      res[n - 2 - count - index][count] = num;
    });

    fn(start, length - 2, count + 1);
  };

  //递归开始
  fn(1, n, 0);
  return res;
}