zoukankan      html  css  js  c++  java
  • 84. Largest Rectangle in Histogram (Array, Stack; DP)

    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 height = [2,1,5,6,2,3],
    return 10.

    法I: 使用动态规划

    class Solution {
    public:
        int largestRectangleArea(vector<int> &height) {
            int* l = new int [height.size()]; //状态:向左连续的>=height[i]的最后一个位置
            int* r = new int [height.size()]; //状态:向右连续的>=height[i]的最后一个位置
        
            l[0]=0;
            for( int i =1; i <height.size(); i++) //从左往右扫描
            {
                if(height[i]==0)
                {
                    l[i] = 0;
                    continue;
                }
                int j = i-1;
                for(; j >= 0; j--){
                    if(height[i] <= height[j]) j = l[j]; //用动态规划求l[i]否则会Time Limit Exceeded
                    if(height[i] > height[j]) break;
                }
                l[i] = j+1;
            }
            r[height.size()-1]=height.size()-1;
            for(int i =height.size()-2; i >=0; i--){ //从右往左扫描
                if(height[i]==0)
                {
                    r[i] = 0;
                    continue;
                }
                int j = i+1;
                for(; j <height.size(); j++){
                    if(height[i] <= height[j]) j = r[j]; //动态规划
                    if(height[i] > height[j]) break;
                }
                r[i] = j-1;
            }
            
            int area;
            int largestArea = 0;
            for(int i = 0; i< height.size(); i++)
            {
                area = (r[i]-l[i]+1) * height[i];
                if(area>largestArea) largestArea = area;
            }
            return largestArea;
        }
    };

    法I的空间负责度是O(n)+O(n), 为了节省空间,可以用stack代替array来存储最高高度的位置。

    法II: stack的栈顶元素表示下一个用来计算面积的高度。

    进栈条件:当前元素比栈顶元素大或相等, 进栈后 i++

    出栈条件:当前元素比栈顶元素小,出栈后 计算面积 i不变(每个元素都要进一次栈,i要等到比自己小的栈顶元素,然后进栈)

    为什么要在此时计算面积?

    这个高度到i位置截至了,无法往有再延伸,所以要在当下计算面积。

    如何界定计算面积时的左界和右界?

    • 左界=新栈顶元素+1
    • 右界=当前位置-1

    为什么可以这样?

    从新栈顶到i的元素高度都>=height[idx],因为如果其中有<height[idx]的元素,那么idx早就出栈了。

    空间复杂度最坏情况也只有O(n)

    class Solution {
    public:
        int largestRectangleArea(vector<int> &height) {
            if(height.size() == 0) return 0;
             
            int res = 0;
            stack<int> idxStack;
            height.push_back(0); //为了如果在最后height高于栈顶元素,能够再进一次else,把stack中的元素pop出来计算
           
            int i = 0;
            int idx;
            int width;
            while(i < height.size())
            {
                if(idxStack.empty() || height[i] >= height[idxStack.top()]){ //当前高度>=栈顶高度
                    idxStack.push(i); //入栈
                    i++;
                }
                else{ //高度降低了
                    idx = idxStack.top();  
                    idxStack.pop(); //出栈
                    width = idxStack.empty() ? i : (i-idxStack.top()-1); //界定左右边界
                    res = max(res, height[idx] * width); //计算面积,并更新最大面积
                }
            }
            height.pop_back();
            return res;
        }
    };
  • 相关阅读:
    WDA基础三:简单的INPUT选择,简单的TABLE显示
    WDA基础二:界面,元素介绍
    WDA基础一:激活相关服务
    docker in all
    神经网络理论与工程实战-知识积累
    信息论理论学习笔记
    机器学习数学知识积累总结
    互联网,IT,大数据,机器学习,AI知识tag云
    java web dev知识积累
    windows系统相关命令及问题排查实践
  • 原文地址:https://www.cnblogs.com/qionglouyuyu/p/4862175.html
Copyright © 2011-2022 走看看