原题地址
https://leetcode.com/problems/maximal-square/description/
题意
给定一个01矩阵,找出这个矩阵中最大的1方阵,返回它的面积。
Example:
matrix:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
result:
4
思路
动态规划。dp是一个vector<int>
的vector
,dp[ i ][ j ]表示以matrix[i][j]为右下角元素的子方阵的最大边长。
遍历matrix的过程中得到解。首先判断matrix[i][j]是否为1,若为1,则先把dp[i][j]置为1;若为0把dp[i][j]置为0,略过本轮循环剩余部分:
如果matrix[i][j]的左上角的dp值(即dp[i-1][j-1])不为0,设k从1到dp[i-1][j-1],迭代过程中matrix[i-k][j]和matrix[i][j-k]都为1则给dp[i][j]加1,否则立即跳出。
每次循环判断一下当前dp值dp[i][j]是否大于之前的最大值,更新。
最后返回最大值的平方即为最大子方阵的面积。
遇到的坑
一开始dp是个二维数组,即
int dp[row][col];
在本地运行也没问题,但是在leetcode上提交就会报runtime error
的错误,改成vector才解决。
循环过程里那些分支条件设置得太多太杂了,写完以后才修改得精简了一些。
在根据dp[i-1][j-1]的值更新dp[i][j]的值时只考虑了dp[i][j]的值更新为dp[i-1][j-1]的情况,所以有时dp[i][j]的值偏小。
代码
class Solution {
public:
int maximalSquare(vector<vector<char> >& matrix) {
int row = matrix.size();
if (row == 0) {
return 0;
}
int col = matrix[0].size();
if (col == 0) {
return 0;
}
vector<vector<int> > dp(row, vector<int>(col, 0));
int maxOrder = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (matrix[i][j] == '1') {
dp[i][j] = 1;
} else {
dp[i][j] = 0;
continue;
}
if (i != 0 && j != 0) {
if (dp[i - 1][j - 1] != 0) {
int order = dp[i - 1][j - 1];
for (int k = 1; k <= order; k++) {
if (matrix[i - k][j] == '1' && matrix[i][j - k] == '1') {
dp[i][j]++;
} else {
break;
}
}
}
}
if (dp[i][j] > maxOrder) {
maxOrder = dp[i][j];
}
}
}
return maxOrder * maxOrder;
}
};