1. 解析
题目大意,从矩阵当中选择面积最大的正方形区域
2. 分析
刚开始看的时候,我也以为跟Surrounded Regions这道题一样,当本题不同在于正方形是个固定的区域,并不是任意发散的,所以本质上这两道题的思路还是不一样的。先解析一种暴力破解的方式,也比较容易理解,用counter数组记录每个列'1'出现的个数,如果是连续出现,即可以认为是长度。
例如 [ [1 0 1 0 0], [1 0 1 1 1], [1 1 1 1 1], [1 0 0 1 0]],从区域第1行至最后一行进行检索,首先检索第一行[ [1 0 1 0 0] ],记录列中出现'1'的个数,宽是确定的,即为当前检索的行 减 起始行 即为1,若当前列连续出现1的长度等于宽,即为正方形区域;接着,检索范围扩大到第二行,[ [1 0 1 0 0], [1 0 1 1 1] ] ,采取同样的方式,如果当前能检测到正方形区域,则更新最大值
第一轮检测区域范围为第1行至第4行[1, 4]: [1, 1]——>[1, 2]——>[1, 3]——>[1, 4]
第二轮检测区域范围为[2, 4]: [2, 2]——>[2, 3]——>[2, 4]
......
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
int res = 0;
for (int row = 0; row < matrix.size(); ++row){
vector<int> counter(matrix[row].size(), 0);
for (int c_row = row; c_row < matrix.size(); ++c_row){
for (int col = 0; col < matrix[c_row].size(); ++col){
if (matrix[c_row][col] == '1') counter[col]++; //记录可能的长
}
res = max(res, getArea(counter, c_row-row+1));
}
}
return res;
}
int getArea(vector<int>& counter, int side_len){ //side_len---宽
if (counter.size() < side_len) return 0;
int count = 0;
for (int col = 0; col < counter.size(); ++col){
if (counter[col] == side_len) count++; //求解区域相邻的长
else count = 0;
if (count == side_len) return side_len * side_len; //正方形区域,即长和宽一样
}
return 0;
}
};
3. 动态规划解法
本题考查的核心,应该就是动态规划,仔细分析,就会发现,若将正方形区域的右下角坐标即为(row, col),则该正方形区域的边长取决于(row, col-1), (row+1, col),(row-1, col-1)的最小值。所以我们可以用二维数组dp[row][col]表示在matrix矩阵当中的该位置所包含的最大正方形区域面积,则状态转移方程为dp[row][col] = min(dp[row][col-1], dp[row-1][col], dp[row-1][col-1] ),当row或者col为0时,dp[row][col] = matrix[row][col] - '0';
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
if (matrix.empty() || matrix[0].empty()) return 0;
int res = 0;
int m = matrix.size(), n = matrix[0].size();
vector<vector<int>> dp(m, vector<int>(n, 0));
for (int row = 0; row < m; ++row){
for (int col = 0; col < n; ++col){
if (row == 0 || col == 0)
dp[row][col] = matrix[row][col] - '0';
else if (matrix[row][col] == '1')
dp[row][col] = min(dp[row-1][col-1], min(dp[row-1][col], dp[row][col-1])) +1;
res = max(res, dp[row][col]);
}
}
return res * res;
}
};