LeetCode Maximal Square

LeetCode Maximal Square

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

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.

题意是给定一个二维字符矩阵,只有0和1字符,要求找出只包含字符1的最大子矩阵,返回其大小。

解题思路:动态规划(DP);DP问题的关键点在于 寻找状态方程,本题我们把状态定义为在(i,j)位置处能达到的只包含字符1的最大矩阵边的长度。这样,面积就是长度的平方。现在关键是计算dp[i][j]。
需要根据matrix矩阵的元素来计算dp。首先需要找到起始位置:由matrix的第一行和第一列计算出dp的第一行和第一列的值,即 dp[i][j] = matrix[i][j] - '0'(其中i=0或j=0)。然后,当i > 0 且 j > 0时,如果matrix[i][j] == '0'那么dp[i][j] = 0(因为题目要求不能包含有‘0’的矩阵);当matrix[i][j] == '1'时,该如何计算dp[i][j]?我们将dp此时的情况写出来:
. . . . . .
. dp[i-1][j-1] dp[i-1][j]
dp[i][j-1] dp[i][j]
. . . . . . .
需要根据dp[i-1][j-1],dp[i-1][j],dp[i][j-1]来计算dp[i][j]。因为其它三个已经在之前计算好了,dp[i][j] = 三者最小值 + 1,;于是
1、i = 0或j = 0时,dp[i][j] = matrix[i][j] - '0'
2、i>0 且 j > 0时,如果matr[i][j] = ‘0’,则dp[i][j]=0;如果matrix[i][j]=‘1’,则dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1

int row = matrix.size();
	if (row == 0)
		return 0;
	int col = matrix[0].size();	

	int maximal = 0;
	vector<vector<int> > dp(row, vector<int> (col, 0));//生成对应于matrix的矩阵

	//根据matrix初始化dp第一列
	for (int i = 0; i < row; i++)
	{
		dp[i][0] = matrix[i][0] - '0';
				maximal = max(maximal, dp[i][0]);
	} 
	//根据matrix初始化dp第一行
	for (int j = 1; j < col; j++)
	{
		dp[0][j] = matrix[0][j]- '0';		
		maximal = max(maximal, dp[0][j]);
	}

	for (int i = 1; i < row; i++)
	{
		for (int j = 1; j < col; j++)
		{
			if (matrix[i][j] == '1')
			{
				dp[i][j] = min(dp[i-1][j], min(dp[i - 1][j - 1], dp[i][j - 1])) + 1;
				maximal = max(maximal, dp[i][j]);
			}
			
		}
	}

	return maximal * maximal;


当然,以上使用了dp矩阵来根据matrix的值来赋值,但其实每次计算的时候并没有使用整个dp矩阵,而只是用了dp[i-1][j-1],dp[i][j-1],dp[i-1][j],因此可以使用两个向量来保存需要的信息,而不是使用整个矩阵:
int row = matrix.size();
	if (row == 0)
		return 0;
	int col = matrix[0].size();

	int maximal = 0;

	vector<int> pre_col(row, 0);//前一列存储的元素
	vector<int> cur_col(row, 0);//当前列存储的元素

	for (int i = 0; i < row; i++)
	{
		pre_col[i] = matrix[i][0] - '0';
		maximal = max(maximal, pre_col[i]);
	}
		
	for (int j = 1; j < col; j++)
	{
		cur_col[0] = matrix[0][j] - '0';
		maximal = max(maximal, cur_col[0]);
		for (int i = 1; i < row; i++)
		{
			if (matrix[i][j] == '1')
			{
				cur_col[i] = min(cur_col[i - 1], min(pre_col[i - 1], pre_col[i])) + 1;
				maximal = max(maximal, cur_col[i]);
			}
		}

		cur_col = pre_col;
		fill(cur_col.begin(), cur_col.end(), 0);
	}

	return maximal * maximal;

当然,也可以就地使用matrix矩阵、而不是用其他辅助空间,但是此时会改动matrix,倘若赋值时超过了char的范围,则越界,程序安全性减低,因此最好不在原来的matrix上做改动。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值