LeetCode:64. 最大正方形 动态规划 时间复杂度O(nm)

64. 最大正方形

题目链接

题目描述

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

示例1:

输入: 

1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0

输出: 4

示例2:

输入: 

0 1 1 0 0
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1

输出: 9

解题思路

这道题的思路是使用动态规划来解决。

首先,我们可以定义一个二维数组 dp,其中 dp[i][j] 表示以矩阵中第 i 行第 j 列为右下角的最大正方形的边长。

然后,我们可以从左上角开始,逐行逐列地更新 dp 数组。

如果当前matrix[i][j]1,则 dp[i][j] 可以由以下三个位置的较小值加 1 得到:

  • dp[i-1][j]
  • dp[i][j-1]
  • dp[i-1][j-1]

依据此,我们可以写出状态转移方程:

dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1

初始条件:

dp[0][j] = 1 if matrix[0][j] == '1'
dp[i][0] = 1 if matrix[i][0] == '1'

最后,我们返回 dp 数组中最大值乘以最大值,即为最大正方形的面积。

复杂度分析

  • 时间复杂度: O ( n m ) O(nm) O(nm),其中 n n n 和 m m m 分别是矩阵的行数和列数。
  • 空间复杂度: O ( n m ) O(nm) O(nm),其中 n n n 和 m m m 分别是矩阵的行数和列数。

代码实现

Go版本

go 复制代码
func maximalSquare(matrix [][]byte) int {
    n:=len(matrix)
    m:=len(matrix[0])
    dp:=make([][]int,n)
    res:=0

    for i:=range dp{
        dp[i]=make([]int,m)
        if(matrix[i][0]=='1'){
            dp[i][0]=1
            res=1
        }
    }

    for j:=0;j<m;j++{
        if(matrix[0][j]=='1'){
            dp[0][j]=1
            res=1
        }
    }


    for  i:=1;i<n;i++{
        for  j:=1;j<m;j++{
           if(matrix[i][j]=='1'){
             dp[i][j]=min(dp[i-1][j],dp[i-1][j-1],dp[i][j-1])+1
           }
           res=max(res,dp[i][j])
        }
    }
    return res*res
}

Python版本

python 复制代码
class Solution(object):
    def maximalSquare(self, matrix):
        n=len(matrix)
        m=len(matrix[0])
        dp=[[0]*m for i in range(n)]
        res=0 

        for i in range(n):
            if matrix[i][0]=='1':
                res=1
                dp[i][0]=1
        
        for j in range(m):
            if matrix[0][j]=='1':
                res=1
                dp[0][j]=1

        for i in range(1,n):
            for j in range(1,m):
                if matrix[i][j]=='1':
                   dp[i][j]=min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1])+1
                   res=max(res,dp[i][j])
        
        return res*res

C++版本

cpp 复制代码
class Solution {
public:
    int maximalSquare(vector<vector<char>>& matrix) {
        int n = matrix.size();
        int m = matrix[0].size();
        vector<vector<int>> dp(n, vector<int>(m, 0));
        int res = 0;

        for (int i = 0; i < n; ++i) {
            if (matrix[i][0] == '1') {
                dp[i][0] = 1;
                res = 1;
            }
        }

        for (int j = 0; j < m; ++j) {
            if (matrix[0][j] == '1') {
                dp[0][j] = 1;
                res = 1;
            }
        }

        for (int i = 1; i < n; ++i) {
            for (int j = 1; j < m; ++j) {
                if (matrix[i][j] == '1') {
                    dp[i][j] = min({dp[i-1][j], dp[i][j-1], dp[i-1][j-1]}) + 1;
                    res = max(res, dp[i][j]);
                }
            }
        }

        return res * res;  
    }
};
相关推荐
weixin_4866811433 分钟前
C++系列-STL容器中统计算法count, count_if
开发语言·c++·算法
一道秘制的小菜41 分钟前
C++第七节课 运算符重载
服务器·开发语言·c++·学习·算法
咕噜咕嘟嘟嘟2 小时前
343. 整数拆分
数据结构·算法
WenGyyyL2 小时前
力扣最热一百题——二叉树的直径
java·c++·算法·二叉树·深度优先
sdlkjaljafdg2 小时前
vector<bool>性能测试
开发语言·c++·算法
muyierfly3 小时前
36.贪心算法3
算法·贪心算法
huanxiangcoco3 小时前
55. 跳跃游戏
python·leetcode
__AtYou__4 小时前
Golang | Leetcode Golang题解之第413题等差数列划分
leetcode·golang·题解
Kenneth風车4 小时前
【机器学习(七)】分类和回归任务-K-近邻 (KNN)算法-Sentosa_DSML社区版
人工智能·算法·低代码·机器学习·分类·数据分析·回归
m0_631270406 小时前
标准C++(二)
开发语言·c++·算法