携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情
题目(Maximal Square)
链接:https://leetcode-cn.com/problems/maximal-square
解决数:1439
通过率:49.2%
标签:数组 动态规划 矩阵
相关公司:amazon google bytedance
在一个由 '0' 和 '1' 组成的二维矩阵内,找到只包含 '1' 的最大正方形,并返回其面积。
示例 1:
输入: matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
输出: 4
示例 2:
输入: matrix = [["0","1"],["1","0"]]
输出: 1
示例 3:
输入: matrix = [["0"]]
输出: 0
提示:
m == matrix.lengthn == matrix[i].length1 <= m, n <= 300matrix[i][j]为'0'或'1'
思路
- 找出最大正方形 => 找出最大边长
- 遍历每一项,1 必然在一个正方形中。0 则不在正方形中
- dp[ i ][ j ] : 以 (i, j) 为 右下顶点 所能形成的最大正方形的边长
- maxSideLength 变量保存最大的正方形边长
- 第 1 行和第 1 列的 '1' 坐标对应的 dp[ i ][ j ] 只能为 1
求归纳通式
- (i, j) 坐标为右下角所能形成的最大正方形的边长,取决于它左边、上方、斜上方的项所能形成的最大正方形的边长,为三者的最小值 + 自身的长度 1
有了base case和递推公式,可以将 dp 二维数组的每一项逐个求出
每次遍历,将求得的 dp[i][j] 与 maxSideLength 比较,尝试更新它
最后返回maxSideLength的平方,求出最大正方形的面积
code
var maximalSquare = function (matrix) {
let maxSideLength = 0 // 相当于纪录保持者
let dp = new Array(matrix.length) // 构建dp数组
for (let i = 0; i < matrix.length; i++) {
dp[i] = new Array(matrix[i].length).fill(0) // dp二维数组,每一项初始化0
for (let j = 0; j < matrix[i].length; j++) {
if (matrix[i][j] === '1') {
if (i === 0 || j === 0) { // base case
dp[i][j] = 1 // 第一列和第一行的dp值只能为1
} else { // 递推通式,求出dp[i][j]
dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1
}
maxSideLength = Math.max(maxSideLength, dp[i][j]) //挑战纪录保持者,试图更新
}
}
}
return maxSideLength * maxSideLength // 边长的平方
};