遍历(预生成数组) 矩阵中最大的正方形

206 阅读2分钟

题目

给定一个N*N的矩降matrix,只有0和1两种值,返回边框全是1的最大正方形的边长长度。 例如:

01111

01001

01001

01111

01011

其中边框全是1的最大正方形的大小为4*4,所以返回4。

  • 遍历规则为从以矩阵中的每个点为构成正方形的左上角定点,正方形的边长范围为该点距离右和下边界最短的距离,以该左上角点+枚举边长值,就能获取所有的正方形,然后又是四个for循环判断每一个正方形的四条边是否都是1构成,最终比较出最大值
  • 正常遍历版本
function process(arr) {
  const row = arr.length;
  const col = arr[0].length;

  for (let i = 0; i < row; i++) {
    for (let j = 0; j < col; j++) {
      // 前两个for循环拿到矩阵中所有的左上角坐标
      // 第三个for循环能找到矩阵中所有的正方形
      // 第三个for循环内的四个for循环遍历每个找到的正方形的四条边是否都是1

      // 以左上角开始能够构成的所有正方形区域应该是左上角坐标距离右和下边界最短的那条距离构成的范围
      // 在该范围内从1开始枚举正方形边长,根据枚举的边长+左上角定点坐标,遍历每个边长对应的四条边是否全是1
      for (let k = 1; k <= Math.min(row - i, col - j); k++) {
        // 遍历四条边上的点是否都是1
        //for(){}
        //for(){}
        //for(){}
        //for(){}
      }
    }
  }
}

优化版本:

  • 通过预处理数组,先遍历出每一个点右边界有多少个连续的1,遍历方向为从下往上,从右往左,然后再遍历出每个点距离下边界有多少个连续的1
  • 通过预处理数组就能省去判断四个边长是否都为1的四个for循环,时间复杂度从O(N^4)优化到了O(N^3)

image.png