leetcode 221. 最大正方形 --javascript dp

1,141 阅读2分钟

221. 最大正方形

题目

在一个由 '0' 和 '1' 组成的二维矩阵内,找到只包含 '1' 的最大正方形,并返回其面积。

image.png

image.png

题解

动态规划(Dynamic Programming, DP)

  • 动态规划只能应用于有最优 子结构的问题。最优子结构的意思是局部最优解能决定全局最优解(对有些问题这个要求并不能完全满足,故有时需要引入一定的近似)。

  • 简单地说,问题能够分解成子问题来解决

  • 通俗一点来讲,动态规划和其它遍历算法(如深/广度优先搜索)都是将原问题拆成多个子问题然后求解,他们之间最本质的区别是,动态规划保存子问题的解,避免重复计算

  • 解决动态规划问题的关键是找到状态转移方程,这样我们可以通计算和储存子问题的解来求解最终问题

  • 同时,我们也可以对动态规划进行空间压缩,起到节省空间消耗的效果。

  • 在一些情况下,动态规划可以看成是带有状态记录(memoization)的优先搜索

  • 动态规划是自下而上的,即先解决子问题,再解决父问题;

  • 而用带有状态记录的优先搜索自上而下的,即从父问题搜索到子问题,若重复搜索到同一个子问题则进行状态记录,防止重复计算。

  • 如果题目需求的是最终状态,那么使用动态搜索比较方便;

  • 如果题目需要输出所有的路径,那么使用带有状态记录的优先搜索会比较方便。

回到本题目

image.png 1、定义一个二维 dp 数组,其中dp[i][j] 表示以 (i, j) 为右下角的正方形, dp[i][j] = k,为边长为k的正方形

2、假设dp[i][j]为k 正上方dp[i-1][j] 斜上方dp[i-1][j-1] 左方dp[i][j-1],都得为最小值k-1,

3、那么dp[i][j]的取值 为matrix[i][j] === 1时候,正上方dp[i-1][j] 斜上方dp[i-1][j-1] 左方dp[i][j-1] 的最小值 加上 此处matrix[i][j] === 1 的值

3、则 (i, j) 位置一定且最大可以构成一个边长为 k 的正方形。

4、状态转移方程dp[i][j] = Math.min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1;

coding

/**
 * @param {character[][]} matrix
 * @return {number}
 */
var maximalSquare = function(matrix) {
    let n = matrix.length, m = matrix[0].length;
    let dp = Array.from({length:n}, ()=> new Array(m).fill(0));
    let max = 0;
    for(let i = 0; i < n; i++) {
        if(matrix[i][0] === '1') {
          dp[i][0] = 1;  
          max = 1;
        }
          
    }
    for(let i = 0; i < m; i++) {
        if(matrix[0][i] === '1') {
          dp[0][i] = 1; 
          max = 1; 
        }
          
    }
    for(let i = 1; i < n; i++) {
        for(let j = 1; j < m; j++) {
            if(matrix[i][j] === '1'){
               dp[i][j] = Math.min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1;
               max = Math.max(dp[i][j], max); 
            }
              
        }
    }
    return max * max;
};