85. 最大矩形

题目描述

给定一个仅包含 01 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。

示例 1:

85. 最大矩形_第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;
    }
};

你可能感兴趣的:(LeetCode错题集,leetcode,c++)