Largest Rectangle in Histogram

思路:

方法一:TLE。时间复杂度O(N^2),空间复杂度O(1)。
对于每一个柱子,往左右两边扩展,不断更新最大的area。
往右扩展:如果右边柱子比当前柱子高,则往右扩。相当于剪枝。
往左扩展:找到目前为止最低的柱子,以此来构成矩形。

class Solution {
public:
    int largestRectangleArea(vector<int>& height) {
        int ans = 0;
        for(int i = 0; i < height.size(); ++i) {
            //prune : find the max i by current i
            for(int k = i + 1; k < height.size(); ++k) {
                if(height[k-1] < height[k]) {
                    i = k;
                }else {
                    i = k - 1;
                    break;
                }
            }
            //calculate from i to far left
            int lowest = height[i];
            for(int j = i; j >= 0; --j) {
                if(height[j] < lowest) {
                    lowest = height[j];
                }
                int current_area = (i - j + 1) * lowest;
                ans = current_area > ans ? current_area : ans;
            }
        }
        return ans;
    }
};

方法二:通过栈来控制。时间复杂度O(N),空间复杂度O(N)。

算法思路非常巧妙,以给定的数据集[2,1,5,6,2,3]为例:

如果栈为空 或者 当前柱子高度大于栈顶柱子高度,则当前柱子索引入栈;
否则,从栈顶不断弹出索引,不断的计算可能的矩形面积。预先往height数组尾端放入一个 0 ,保证会计算最后的height。

i = 0 时,栈为空,把第0号柱子压栈;

i = 1 时,第1号柱子高度1小于栈顶柱子高度2,出栈并计算面积;

栈空,第1号柱子入栈;

i = 2 时,第2号柱子高度5大于栈顶柱子高度1,入栈;

i = 3 时,第6号柱子高度6大于栈顶柱子高度5,入栈;

可以看出,栈中的所在索引的柱子高度一定是递增的;

i = 4 时,第4号柱子高度2小于栈顶柱子高度6,出栈并计算面积;

第4号柱子高度2继续小于栈顶柱子高度5,出栈并计算面积;

第4号柱子高度2大于栈顶柱子高度1,第4号柱子入栈;

i = 5 时,第5号柱子高度3大于栈顶柱子高度2,入栈;

这时轮到了提前放入height数组中的 0

第6号柱子高度0小于栈顶柱子高度3,出栈并计算面积;

第6号柱子高度0小于栈顶柱子高度2,出栈并计算面积;

第6号柱子高度0小于栈顶柱子高度1,出栈并计算面积;

之后,第0号柱子入栈,for循环条件不满足退出。

返回所有得到面积的最大值,over。

class Solution {
public:
    int largestRectangleArea(vector<int>& height) {
        stack<int> s;
        height.push_back(0);
        int ans = 0;
        for(int i = 0; i < height.size();) {
            if(s.empty() || height[i] > height[s.top()]) {
                s.push(i);
                ++i;
            }else {
                int tmp = s.top();
                s.pop();
                ans = max(ans, height[tmp] * (s.empty() ? i : i - s.top() - 1));
            }
        }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值