LeetCode 84

Leetcode 84 Largest Rectangle in Histogram

Description

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].


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

题意分析

题目的意思很容易理解,就是在这个很多个矩形的图中,算出图中面积最大的矩形。比如上述例子中,面积最大的是由5、6两个矩形凑在一起形成的面积为10的矩形
然后解法的话如果直接暴力去算的话,算法复杂度会很大,用栈的话可以下降到O(n),下面是第一种用栈的解法。
第一种解法的话就是初始化栈:
(1)如果栈空或者第i个矩形高度大于栈顶,入栈
(2)取出栈中所有高度比第i个矩形高的矩形,然后计数count,然后因为第i个要进栈的元素和栈中的元素的高度都比出栈元素的大,所以这些矩形中能利用到自己最大高度的宽度就是出栈几个元素的个数(可以理解为横截的矩形个数),然后如果这些面积大于结果res,则把res设为该面积

(3)剩下如果栈未空的话,栈顶是最高,按照相同的办法取出相应矩形的面积作比较得出结果

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        stack<int> st;
        int res = 0, count = 0;
        for (int i = 0; i < heights.size(); i++) {
            if (st.empty() || heights[i] >= st.top()) {
                st.push(heights[i]);
            }
            else {
                count = 0;
                while (!st.empty() && heights[i] < st.top()) {
                int temp = st.top();
                st.pop();
                count++;
                res = max(res, count * temp);
                }
                while (count--)
                    st.push(heights[i]);
                st.push(heights[i]);
            }
        }
        count = 1;
        int size = st.size();
        for (int i = 0; i < size; i++) {
            res = max(res, count * st.top());
            st.pop();
            count++;
        }
        return res;
    }
};

第二种方法也是用栈,但是过程略为麻烦,用栈来储存索引,初始化栈以后:
(1)如果栈空或者元素i要大于栈顶元素,直接进栈
(2)首先获取栈顶元素的高度,然后pop,如果栈空了,那么说明出去的这个元素是最矮的元素,宽度就是这个元素的下标,如果栈没空,那宽度就是i - 1 - top的高度,top指的是栈顶的下标,注意这个时候top已经发生了变化
(3)如果最后栈没空,那剩下的都是最矮的元素,直接用原始的size计算宽度再到面积。

class Solution {
 public:
     int largestRectangleArea(vector<int> &height) {
         stack<int> st;
         int s = height.size(), ans = 0, h, w;
         for (int i = 0; i < s; i++) {
         // 相等的时候会把这个重新进行一次,然后在计算宽度的时候多1,因为top已经发生了变化
             while (!st.empty() && height[st.top()] >= height[i]) {
                 h = height[st.top()];
                 st.pop();
                 if (st.empty()) 
                    w = i;
                 else
                    w = i - 1 - st.top();
                 if (ans < h * w) ans = h * w;
             }
             st.push(i);
         }
         // 这里不用重置size,因为pop出去的长方形高度一定要比剩下的要小
        while (!st.empty()) {
             h = height[st.top()];
             st.pop();
             w = st.empty() ? s: s - 1 - st.top();
             if (ans < h * w) ans = h * w;
         }
         return ans;
     }
 };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值