
85. 最大矩形
给定一个仅包含 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’
当我们以0~i行遍历的时候,将每一行看作新的横坐标,此时可以看作一个个的矩阵放置一起。问题实际上就可以转化为柱状图中最大的矩形

注意,第一次遍历的时候,左边界是栈顶pop后top的结果,而不是栈顶本身!!因为前面可能遇到更高的但是被出掉了,此时如下标2,左边界就是0,右边界就是3。
第二次的时候右边界始终固定,左边界就是栈顶的元素。

class Solution {
public:
int maximalRectangle(vector<vector<char>> matrix) {
if (matrix.empty()) return 0;
vector<int> heights(matrix[0].size(), 0);
int res = 0;
for (int i = 0; i < matrix.size(); ++i)
{
for (int j = 0; j < matrix[i].size(); ++j)
{
//从上到下看就是一个个矩形
if (matrix[i][j] == '1')
{
heights[j] ++;
}
else
{//表示后续都需要从0开始计算
heights[j] = 0;
}
}
res = max(res, GetMaxResult(heights));
}
return res;
}
int GetMaxResult(vector<int>& heights)//单调栈的逻辑
{
stack<int> st;//如下标
int result = 0;
for (int i = 0; i < heights.size(); ++i)
{
if (st.empty())
{
st.push(i);
}
else
{
if (heights[st.top()] <= heights[i])
{
st.push(i);
}
else
{
while (!st.empty() && heights[st.top()] > heights[i])
{//右边界是i,左边界是curIndex
int tmp = 0;
int curIndex = st.top();
st.pop();
int pre = -1;
if (!st.empty())
{
pre = st.top();
}
tmp = (i - pre - 1) * heights[curIndex];//curIndex false
result = max(tmp, result);
}
st.push(i);//入新下标
}
}
}
while (!st.empty())
{
int curIndex = st.top();
st.pop();
if (st.empty())
{//最后一个的边界时heights.size()
int tmp = heights[curIndex] * heights.size();
result = max(tmp, result);
}
else
{//右边界是最右边
int preIndex = st.top();
//右边界此时都是最右边,因为有比他小的该下标已经出掉了
int tmp = heights[curIndex] * (heights.size() - 1 - preIndex);
result = max(tmp, result);
}
}
return result;
}
};
end