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 得到:

  • dpi-1j
  • dpij-1
  • dpi-1j-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;  
    }
};
相关推荐
晴天的雨.9927 小时前
【C++算法】和为s的两个数
开发语言·数据结构·c++·算法
aramae14 小时前
MySQL复合查询(8)
java·c语言·开发语言·后端·算法
荆棘鸟智能14 小时前
城市感知设备怎么统一接入?从多协议网关到设备模型的中间件架构设计
人工智能·算法·边缘计算
INGNIGHT18 小时前
270 · 电话号码的字母组合II(Trie)
linux·算法
2401_8390805418 小时前
C++常见八股
数据结构·c++·算法
青山是哪个青山19 小时前
LeetCode 188:买卖股票的最佳时机 IV
算法
mikuyyds19 小时前
geo-toolbox 插件算法解析:RUSLE 与 MUSLE 的工程化落地
算法·rust·gis
Tisfy19 小时前
LeetCode 3498.字符串的反转度:一次遍历
leetcode·字符串·题解·遍历
a1879272183119 小时前
【算法】树(二):队列与祖先——BFS 骨架三配件、短路透传与合流
算法·leetcode·二叉树··bfs·算法讲解·树遍历
syagain_zsx20 小时前
算法基础篇 · 03 枚举(C++ 题解)
c++·算法·二进制·枚举