前端算法必刷题系列[91]

1,182 阅读3分钟

这是我参与8月更文挑战的第25天,活动详情查看:8月更文挑战

这个系列没啥花头,就是纯 leetcode 题目拆解分析,不求用骚气的一行或者小众取巧解法,而是用清晰的代码和足够简单的思路帮你理清题意。让你在面试中再也不怕算法笔试。

166. 最大正方形 (maximal-square)

标签

  • 动态规划
  • 中等

题目

leetcode 传送门

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

示例 1

image.png

输入:matrix = [
["1","0","1","0","0"],
["1","0","1","1","1"],
["1","1","1","1","1"],
["1","0","0","1","0"]]
输出:4

示例 2

image.png

输入:matrix = [
["0","1"],
["1","0"]]
输出:1

基本思路

其实大部分求最值问题,动态规划的解法都适用。

动态规划这篇我们了解到动态规划的基本步骤是下面三步:

  1. 寻找最优子结构(状态表示)
  2. 归纳状态转移方程(状态计算)
  3. 边界初始化

我们还是根据之前的基本步骤来

  1. 状态表示:

目标是正方形面积,可以转化成找出最大边长来代替

而我们要求的是整个矩阵的最大边长的话,就以 [i, j] 做为右下角坐标,那么 可以设置

dp[i][j]右下角坐标, 能形成的最大正方形边长。这样假设矩阵是 m * n, dp[m][n] 为右下角,得出答案后再平方就是面积。

  1. 状态转移方程:

image.png

  1. 边界初始化:

首先前提条件要是 matrix[i][j] === '1', 边界上 i === 0 或者 j === 0 的情况下 , dp[i][j] = 1这很好理解,贴边上的最大也就是 1 为边长。(i ,j) 是右下角注意。

右下角为 坐标[i][j],它要向左上方去看历史情况

如果(i, j)的值是 1,则 dp(i,j) 的值由其上方、左方和左上方三个相邻位置的 dp 值决定。具体而言,当前位置的元素值等于三个相邻位置的元素中的最小值加 1。因为你要都是 1 的正方形,根据木桶原理,取最短的都是 1 的情况才行。

代码实现

const maximalSquare = (matrix) => {
  let maxLen = 0, rows = matrix.length, cols = matrix[0].length

  // 建立 dp
  let dp = new Array(rows).fill(0).map(() => new Array(cols).fill(0))

  for (let i = 0; i < rows; i++) {
    for (let j = 0; j < cols; j++) {
      // 当角上是 1 计算才有意义
      if (matrix[i][j] === '1') {
        // 角贴边,肯定最大只能是1了, 这是边界条件
        if (i === 0 || j === 0) {
          dp[i][j] = 1
        } else {
          // 木桶原理,取最短的一边为边长
          dp[i][j] = Math.min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1
        }
        // 每轮更新最大值
        maxLen = Math.max(maxLen, dp[i][j])
      }
    }
  }
  return maxLen * maxLen;
};

let matrix = [
["1","0","1","0","0"],
["1","0","1","1","1"],
["1","1","1","1","1"],
["1","0","0","1","0"]]

console.log(maximalSquare(matrix))

注释应该比较清晰了

另外向大家着重推荐下这个系列的文章,非常深入浅出,对前端进阶的同学非常有作用,墙裂推荐!!!核心概念和算法拆解系列

今天就到这儿,想跟我一起刷题的小伙伴可以加我微信哦 点击此处交个朋友 Or 搜索我的微信号infinity_9368,可以聊天说地 加我暗号 "天王盖地虎" 下一句的英文,验证消息请发给我 presious tower shock the rever monster,我看到就通过,加了之后我会尽我所能帮你,但是注意提问方式,建议先看这篇文章:提问的智慧

参考