IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> LeetCode之最大正方形(暴力求解和动态规划求解) -> 正文阅读

[数据结构与算法]LeetCode之最大正方形(暴力求解和动态规划求解)

题目

在一个由 '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.length
n == matrix[i].length
1 <= m, n <= 300
matrix[i][j] 为 '0' 或 '1'

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/maximal-square
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

1.暴力求解? ? ? ??

????????我一开始没有想到动态规划,只想到了暴力求解:就是依次扫每一个格子,看是否满足以它为正方形的左上角构成的最大正方形。

# 暴力解法:从可能的最大情况下,一个一个的去扫整个矩形
class Solution:
    def maximalSquare(self, matrix: List[List[str]]) -> int:
        m, n = len(matrix), len(matrix[0])  # m行n列
        max_len = min(m, n)  # 正方形的最大边为m,n中较小的一个值
        for cur_len in range(max_len, -1, -1):  # 当前正方形的边长
            i = 0
            while i <= m - cur_len:  # 垂直方向的移动
                j = 0
                next_i_len = cur_len
                while j <= n - cur_len:  # 水平方向的移动
                    next_j_len = 1
                    cur_square = matrix[i:i + cur_len]  # 当前正方形
                    for row_index in range(cur_len):
                        row = cur_square[row_index]
                        cur_row = row[j:j + cur_len]  # 当前正方形的每一行
                        flag = 0  # 用于判断要不要退出当前的外层循环(i层的)
                        for k in range(cur_len - 1, -1, -1):
                            if cur_row[k] == '0':  # 从每一行的最后一个数开始判断,只要等于0,就不能构成当前最大的正方形
                                next_j_len = max(next_j_len, k + 1)  # 计算下一步水平位移的增量,而不是每一次只增加1,这样节省了很多时间
                                flag = 1
                                break  # 因为不能构成当前最大的正方形,所以直接跳出循环(j层的)
                        if flag:
                            next_i_len = min(next_i_len, row_index + 1)  # 计算垂直方向的移动增量,而不是每一次只增1,这样子节省了很多时间
                            break  # 因为正方形中有0出现,所以也跳出i层循环
                    else:  # 如果当前的正方形都是由1组成的,则不会从上面的for循环由break跳出 那么当前的正方形就是面积最大的正方形,直接return即可
                        print(f'最长边:{cur_len}')
                        return cur_len ** 2

                    print(f'{next_i_len}*' * 100)
                    j += next_j_len  # 水平方向的移动
                i += next_i_len  # 垂直方向的移动

2.动态规划

? ? ? ? 后来看了题解后,可以用动态规划求解,与上面不一样的是,这里选一个点作为正方形的最右下角的那个顶点,然后在这个点上记录能够组成的最大的正方形的边,而它的取值和它自身是否为0有关;同时和它左边,上边和左上角的点的值有关,具体的状态转移方程如下:

# 假设dp[i][j]表示的以(i,j)为右下角的最大正方的边长
# 则dp[i][j]的值由其左边,上边和左上角的值共同确定

则dp[i][j]的值的确定可能出现两种情况:
    1.matrix[i][j]=0,则dp[i][j]直接等于0
    2.matrix[i][j]!=0,则比较其左边,上边和左上角的值,dp[i][j]=min(dp[i-1][j],dp[i][j-1],d[i-1][j-1])+1
# 动态规划求解
class Solution:
    def maximalSquare(self, matrix: List[List[str]]) -> int:
        m, n = len(matrix), len(matrix[0])
        dp = [[0 for j in range(n)] for i in range(m)]  # 初始化一个dp数组
        dp[0] = [int(i) for i in matrix[0]]  # 更新dp第一行的值,和matrix中第一行的值相同
        max_len = max(dp[0])  # 记录最长边
        if m > 1:
            for i in range(m):
                dp[i][0] = int(matrix[i][0])  # 更新dp第一列的值,和matrix中第一列的值相同
            dp[1][0] = int(matrix[1][0])
            max_len = max(max_len, dp[1][0])
            for i in range(1, m):
                for j in range(1, n):
                    if matrix[i][j] == '0':
                        dp[i][j] = 0
                    else:
                        dp[i][j] = min(int(dp[i - 1][j]), int(dp[i][j - 1]), int(dp[i - 1][j - 1])) + 1
                    max_len = max(max_len, dp[i][j])
        return max_len ** 2

通过截图

?同步更新于个人博客系统:LeetCode之最大正方形(暴力求解和动态规划求解)

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-07-20 19:09:52  更:2022-07-20 19:12:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 23:44:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码