思路——01 螺旋矩阵

164 阅读2分钟
  因为正常for循环得到的数是一个顺序排列的,,,但是螺旋矩阵的顺序是改变的,因而方法中需要再去单独创建一个x和y记录实际对应的坐标
  class ComputeMatirx {
     /**
        @method 构建空数组
        @parame len 数据长度
     **/
     setBaseMatirx(len) {
        const baseMatirx = []
        for (let i = 0; i < len; i++) {
           baseMatirx.push([])
        }
        return baseMatirx
     }
     /**
        @method 一圈一圈进行,依次遍历填充螺旋矩阵最外层的数据
        @parame baseNum 初始值
        @parame baseSpac 数据间隔
        @parame len 数据长度
     **/
     getFirMatirx(baseNum, baseSpace, len) {
        const baseMatirx = this.setBaseMatirx(len)
        let row = 0// 行
        let col = 0// 列
        let minNum = 0 // 最小行列
        let maxNum = len - 1// 最大行列
        /**
         思路(4阶为例):1,2,3,4对应坐标是(00,01,02,03),类似c
        **/
        for (let i = 0; i < Math.pow(len, 2); i++) {
           baseMatirx[row][col] = i * baseSpace + baseNum //
           if (row === maxNum && col > minNum) {
              // 第三步 col =3 row =3(32,31,30)
              col = col - 1
              // col = 0 row =3
           } else if (col === minNum && row > minNum) {
              // 第四步 col = 0 row =3(20,10)
              row = row - 1
              // col = 0 row =1
           } else if (col === maxNum && row < maxNum) {
              // 第二步 col = 3 row =0 (13,23,33)
              row = row + 1
              // col =3 row =3
           } else if (row === minNum && col < maxNum) {
              // 第一步 row = 0 (00,01,02,03)
              col = col + 1
              // col = 3 row =0
           }
           if (row - 1 === minNum && col === minNum) {
              // 第五步  col = 0 row =1
              minNum = minNum + 1
              maxNum = maxNum - 1
              // minNum =1  maxNum =2 进入下一圈
           }
        }
        return baseMatirx
     }
     /**
        @method 中间往外旋转,依靠区域划分的规则,沿对角线分割分为四个区域,不同区域对应的x++,x--,y++,y--四种情况
        @parame baseNum 初始值
        @parame baseSpac 数据间隔
        @parame len 数据长度
     **/
     getSecMatirx(baseNum, baseSpace, len) {
        const baseMatirx = this.setBaseMatirx(len)
        const centerMile = len % 2 === 0 ? len / 2 : (len - 1) / 2 // 中心距离,需要判断len的奇偶分别赋值
        let x = centerMile// 中心点位置x(对应行)
        let y = centerMile// 中心点位置y(对应列)
        // 第一步,x=2,y=2
        /**
         思路(5阶为例,baseNum=1, baseSpace=1),
         5*5的区域被y=x和y=-x+4(y=len-x-1)两条线分为四个区域,
         从中间开始,其它区域数的坐标相对于中间数的坐标,呈现x++,x--,y++,y--四种情况
        **/
        for (let i = 0; i < Math.pow(len, 2); i++) {
           // 因为数是从中间往两边扩散计算,所以最中间的数由最大项开始计算
           baseMatirx[y][ len - x - 1] = (Math.pow(len, 2) - i - 1) * baseSpace + baseNum
           // 第二步,baseMatirx[2][2]=25,i=0
           // 第四步,baseMatirx[2][1]=24,i=1
           if (x <= len - y - 1 && x >= y) {
              x++
              // 第三步 x=3,y=2
           } else if (x > len - y - 1 && x > y) {
              y++
           } else if (x > len - y - 1 && x <= y) {
              x--
           } else if (x <= len - y - 1 && x < y) {
              y--
           }
        }
        return baseMatirx
     }
  }
  const matirx = new ComputeMatirx()
  const firMatirx = matirx.getFirMatirx(1, 1, 10)
  const secMatirx = matirx.getSecMatirx(1, 1, 9)
  console.log(firMatirx)
  console.log(secMatirx)