题目描述
给定一个仅包含 0
和 1
、大小为 rows x cols
的二维二进制矩阵,找出只包含 1
的最大矩形,并返回其面积。
示例 1:
输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
输出:6
解释:最大矩形如上图所示。
示例 2:
输入:matrix = []
输出:0
示例 3:
输入:matrix = [["0"]]
输出:0
示例 4:
输入:matrix = [["1"]]
输出:1
示例 5:
输入:matrix = [["0","0"]]
输出:0
提示:
rows == matrix.length
cols == matrix[0].length
1 <= row, cols <= 200
matrix[i][j]
为'0'
或'1'
解答
class Solution {
public:
int maximalRectangle(vector<vector<char>>& matrix) {
// 利用 84.柱状图中最大的矩形的思路
// 在每一行最左边建立一个坐标轴,每列连续1的数量就是矩形高度
// 就可以转换为求柱状图中最大的矩形
if(matrix.size() == 0)
{
return 0;
}
vector<int> heights(matrix[0].size());
int maxArea;
// 每一行都求一次最大矩形
for(int row = 0; row < matrix.size(); row++)
{
// 求出某一行每列的高度
for(int col = 0; col < matrix[0].size(); col++)
{
if(matrix[row][col] == '1')
{
heights[col] += 1;
}
else // 同一列1不连续,高度重置为1
{
heights[col] = 0;
}
}
maxArea = max(maxArea, largestRectangleArea(heights));
}
return maxArea;
}
// 求每行的最大矩形
int largestRectangleArea(vector<int> &heights)
{
int maxArea = 0;
stack<int> st;
int p = 0;
while(p < heights.size())
{
// 栈空入栈
if(st.empty())
{
st.push(p);
p++;
}
else
{
int top = st.top();
// 当前高度大于栈顶入栈
// 保证栈顶到栈底降序
if(heights[p] >= heights[top])
{
st.push(p);
p++;
}
else // 当前高度小于小于栈顶对应的右边界,出栈
{
int height = heights[st.top()];
st.pop();
// 左边第一个小于当前柱子的下标
int left = st.empty() ? -1 : st.top();
// 右边第一个小于当前柱子的下标
int right = p;
maxArea = max(maxArea, (right - left - 1) * height);
}
}
}
// 【左边界】从【右往左】扩展进行判断是否得到最大矩形
while(!st.empty()) // 柱状图完全递增的情况
{
int height = heights[st.top()];
st.pop();
// 左边第一个小于当前柱子下标
int left = st.empty() ? -1 : st.top();
// 右边没有小于当前高度的柱子
int right = heights.size();
maxArea = max(maxArea, (right - left - 1) * height);
}
return maxArea;
}
};