最大正方形

Given a 2D binary matrix filled with 0's and 1's, find the largest square containing all 1's and return its area.

 
Example

For example, given the following matrix:

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

Return 4.


判断:dp[i][j]为最大正方形的右下角,则dp[i-1][j-1],dp[i-1][j],dp[i][j-1]是几个正方形的右下角。否则,dp[i][j]所属的正方形是自己。

正方形的边长:dp[i][j]是dp[i-1][j],dp[i-1][j-1],dp[i][j-1]中最小+1.

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

#include <iostream>
using namespace std;
int dp[1005][1005],g[1005][1005];
int hs(int x,int y)
{
	int s,i,j;
	s=0;
	for(i=0;i<x;i++)
		for(j=0;j<y;j++)
		{
			dp[i][j]=(g[i][j]+1)%2;
			s|=dp[i][j];
		}
	for(i=1;i<x;i++)
		for(j=1;j<y;j++)
		{
			if(g[i][j])
				dp[i][j]=0;
			else
			{
				dp[i][j]=min(dp[i-1][j-1],min(dp[i-1][j],dp[i][j-1]))+1;
				s=max(s,dp[i][j]);
			}
		}
	return s*s;
}
int main()
{
	int h,w;
	int i,j;
	cin>>h>>w;
	for(i=0;i<h;i++)
		for(j=0;j<w;j++)
			cin>>g[i][j];
	cout<<hs(h,w);
	return 0;
}




<think>好的,我需要帮助用户找到LeetCode上最大正方形问题的Python动态规划解法。首先,我得回忆一下这个问题的大致内容。题目应该是在一个由'0'和'1'组成的二维矩阵中,找到只包含'1'的最大正方形的面积,并返回其面积。对吗?然后用户特别提到了动态规划的方法,所以我要集中在这个解法上。 接下来,我应该先回想动态规划解决这个问题的思路。通常动态规划问题需要定义状态和状态转移方程。对于最大正方形,我记得状态dp[i][j]可能表示以(i,j)为右下角的最大正方形的边长。这样的话,如果当前格子是'1',那么dp[i][j]的值取决于左边、上边和左上角的三个dp值中的最小值加一。这个部分是否正确呢?比如,当这三个方向的最小值是2时,说明当前点可以构成一个3x3的正方形。这个逻辑对吗?我需要确认一下。 然后,我需要考虑初始条件。第一行和第一列的dp值应该就是该位置的值本身,如果是'1'的话,边长就是1,否则是0。接下来遍历矩阵的其他位置,按照状态转移方程更新dp数组。同时,要维护一个变量来记录当前找到的最大边长,最后返回边长的平方作为面积。 接下来,我应该考虑如何将这个思路转化为Python代码。可能需要初始化一个与原矩阵大小相同的dp数组。或者,为了优化空间,是否可以使用原矩阵来保存dp值?但原矩阵的元素是字符串类型,可能需要转换。不过通常动态规划解法会新建一个dp数组,或者用一维数组来优化空间,但用户可能更关注基础解法,所以先按二维数组来处理。 然后,代码的大致结构应该是这样的:遍历每个元素,如果是'1',则计算dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1,否则dp[i][j]保持0。同时更新最大边长。最后返回最大边长的平方。 需要注意边界情况,比如矩阵为空,或者只有一行或一列的情况。这时候最大正方形的面积就是是否存在'1',存在的话就是1,否则0。 接下来,我需要参考用户提供的引用内容。用户引用了多个关于动态规划最大正方形的资料,比如引用1和引用3、4提到了动态规划解法的步骤和代码示例。可能需要看看这些引用中的代码结构,确保我的回答与这些资源一致,以便正确引用。 例如,引用4中的Python代码可能是这样的: def maximalSquare(self, matrix: List[List[str]]) -> int: # 初始化dp数组 # 遍历矩阵 # 更新dp和最大边长 # 返回平方 我需要确保我的代码与这种结构一致,并且正确使用动态规划的状态转移方程。 另外,用户提供的引用3和4可能已经包含了正确的解法,所以我的任务是将这些信息整合成清晰的步骤,并给出正确的代码示例,同时附上引用标识。 然后,我需要检查是否有常见的错误点。例如,矩阵中的元素是字符串类型,需要转换为整数吗?或者在计算min的时候是否正确处理了边界情况?比如当i或j为0时,dp数组的处理是否正确。 最后,生成相关问题的时候,需要围绕动态规划、优化方法、类似题目等展开,比如如何优化空间复杂度,或者不同路径问题等,可以参考用户提供的引用中的相关内容。 总结一下,我需要分步骤解释动态规划的解法,给出正确的Python代码,并确保引用正确来源。同时,生成的相关问题要符合用户提供的引用中的主题,比如动态规划的其他应用或优化方法。</think>### LeetCode 221. 最大正方形 Python 动态规划解法 #### 问题描述 给定一个由 `'0'` 和 `'1'` 组成的二维矩阵,找到只包含 `'1'` 的最大正方形,并返回其面积。 #### 动态规划解法步骤 1. **状态定义** 定义 $dp[i][j]$ 表示以矩阵第 $i$ 行第 $j$ 列元素为右下角的最大正方形边长。 2. **状态转移方程** - 若 $matrix[i][j] = '0'$,则 $dp[i][j] = 0$(无法构成正方形)。 - 若 $matrix[i][j] = '1'$,则: $$ dp[i][j] = \min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1 $$ 这个公式表示当前正方形的边长由左、上、左上三个方向的最小值决定[^3][^4]。 3. **初始条件** - 第一行和第一列直接取原矩阵的值(若为 `'1'` 则边长为 1)。 4. **维护最大值** 在遍历过程中记录最大边长 $max\_side$,最终面积为 $max\_side^2$。 #### 代码实现 ```python def maximalSquare(matrix): if not matrix: return 0 rows, cols = len(matrix), len(matrix[0]) dp = [[0] * cols for _ in range(rows)] max_side = 0 for i in range(rows): for j in range(cols): if matrix[i][j] == '1': if i == 0 or j == 0: # 第一行或第一列 dp[i][j] = 1 else: dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1 max_side = max(max_side, dp[i][j]) return max_side * max_side ``` #### 代码解释 - **边界处理**:矩阵为空时直接返回 0。 - **初始化二维 DP 数组**:大小与输入矩阵相同。 - **遍历顺序**:逐行逐列遍历,若当前元素为 `'1'` 则更新 $dp[i][j]$。 - **空间复杂度**:$O(m \times n)$,可通过滚动数组优化到 $O(n)$[^2]。 #### 示例 输入: $$ matrix = [["1","0","1","0","0"], ["1","0","1","1","1"], ["1","1","1","1","1"], ["1","0","0","1","0"]] $$ 输出:4(边长为 2 的正方形)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值