class Solution {// 最大正方形面积
public:
int maximalSquare(vector<vector<char>>& matrix) {
if (matrix.empty()) { return 0; }
long len = 0;
vector<vector<int>> dp(matrix.size(), vector<int>(matrix[0].size(), 0));
for (int row = 0; row < matrix.size(); ++row)
for (int col = 0; col < matrix[row].size(); ++col){
if (!col || !row)
dp[row][col] = matrix[row][col] - '0';
else if (matrix[row][col] != '0'){
if (dp[row][col - 1] != dp[row - 1][col])
dp[row][col] = min (dp[row][col - 1], dp[row - 1][col]) + 1;
else{
int len = dp[row][col - 1];
dp[row][col] = len;
// error: if(dp[row - len][col - len]): tricky! for instance {{0,0},{0,1}}
// dp[1][1] equals to 1, but we get 0
if (matrix[row - len][col - len] != '0')
dp[row][col]++;
}
}
len = max (len, static_cast<long>(dp[row][col]));
}
return len * len;
}
};
void buildHistogram(vector<string> &matrix, vector<vector<int>>& histogram) { // 构造图
for (int col = 0; col < matrix[0].size(); ++col)
for (int row = (int)matrix.size() - 1; row >= 0; --row) {
if (matrix[row][col] != '0') {
histogram[row][col] = 1;
if (row < (int)matrix.size() - 1)
histogram[row][col] += histogram[row + 1][col];
}
}
}
int rowMaxRectangle(vector<int>& heights) {// 利用升序栈
int ret = 0;
stack<int> _stack;
for (int i = 0; i < heights.size();) {
if (_stack.empty() || heights[_stack.top()] <= heights[i])
_stack.push(i++);
else {
int val = heights[_stack.top()];
_stack.pop();
int leftPos = _stack.empty() ? 0 : (_stack.top() + 1);
ret = max(ret, val * (i - leftPos));
}
}
while (!_stack.empty()) {
int val = heights[_stack.top()];
_stack.pop();
int leftPos = _stack.empty() ? 0 : (_stack.top() + 1);
ret = max(ret, val * ((int)heights.size() - leftPos));
}
return ret;
}
int maxRectangle(vector<string> &matrix) { // 求最大长方形
if (matrix.empty())
return 0;
vector<vector<int>> histogram(matrix.size(), vector<int>(matrix[0].size(), 0));
buildHistogram(matrix, histogram);
int ret = 0;
for (auto heights : histogram)
ret = max(ret, rowMaxRectangle(heights));
return ret;
}