leetcode——Maximal Rectangle

题目:

Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.


Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].


The largest rectangle is shown in the shaded area, which has area = 10 unit.

For example,
Given heights = [2,1,5,6,2,3],
return 10.

分析:比较直观的想法就是分别从每个柱子向前向后扩展,知道遇到低于它的柱子为止,这种方法的时间复杂度是o(n^2)。那么能不能在o(1)的时间复杂度就得到某个柱子向左向右第一个低于它的柱子的位置呢?

维护一个栈,存储柱子的位置(下标),遍历每个柱子,如果当前柱子的高度大于栈顶柱子的高度,那么压栈(在栈中,某个元素的直接前驱就是左边比它低的柱子的下标);否则出栈,并从刚出栈的柱子左右延伸(左边止于新的栈顶,右边止于当前柱子)计算矩形面积。重复这个过程,直到每个柱子都被压入并弹出过(所以,为了保证最后一个柱子被压入和弹出,在数组最后添加一个0)。

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        stack<int> s;
        heights.push_back(0);
        int maxArea = 0;
        for (int i = 0; i < heights.size(); ++i) 
        {
            
            if (s.empty() || heights[i] >= heights[s.top()])
            {
                s.push(i);
            }
            else 
            {
                int tmp = s.top();
                s.pop();
                maxArea = max(maxArea, heights[tmp] * (s.empty() ? i : i - s.top() - 1));
            
                --i;//要注意,i不能增加,因为i还没有被压入
            }
        }
        return maxArea;
    }
};
题目:

Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.

分析:

遍历矩阵的每一个元素,然后以该元素作为矩形的左下角,找出一个最大矩形。如果对矩阵的每一行都建立一个直方图,直方图的横向为列下标,直方图的柱子高度就是在该列上从该行开始向上出现的连续1的个数,比如


在直方图中找最大矩形的方法上面已经讲过,整个算法时间复杂度o(n^2).

class Solution {
public:
    int maximalRectangle(vector<vector<char>>& matrix) {
        if (matrix.empty() || matrix[0].empty()) 
        {
            return 0;
        }
        int m = matrix.size(), n = matrix[0].size();
        vector<int> h(n + 1, 0);//直方图,在最后添加了0
        int maxArea = 0;
        for (int i = 0; i < m; ++i)//在每一行上建立直方图 
        {
            for (int j = 0; j < n; ++j) //对第i行建立直方图
            {
                if (matrix[i][j] == '1') 
                {
                    h[j]++;
                }
                else 
                {
                    h[j] = 0;
                }
            }
            
            //直方图建立完成,在直方图中找最大矩形
            stack<int> s;
            for (int j = 0; j <= n; ++j) 
            {
                if (s.empty() || h[j] >= h[s.top()])
                {
                    s.push(j);
                }
                else 
                {
                    int tmp = s.top();
                    s.pop();
                    maxArea = max(maxArea, h[tmp] * (s.empty() ? j : j - s.top() - 1));
            
                    --j;//要注意,i不能增加,因为i还没有被压入
                }
            }
        }
        return maxArea;
    }
};




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值