zoukankan      html  css  js  c++  java
  • LeetCode84 Largest Rectangle in Histogram

    题目:

    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. (Hard)

    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.

    分析:

    非常经典的一道题目,想了好久也没想出来,还是参考了讨论区。

    题意是找到最大的直方图面积。显而易见的思路是对于每个高度heights[i],向左向右找到第一个小于它的位置,即为以此高度能组成的最大直方图面积。

    循环下来求得所有高度为底线的最大直方图面积,求max即可。

    但寻找左右边界的时间复杂度O(n),遍历的时间复杂度也是O(n), O(n^2)的算法是超时的。

    中间自己还想到了一些简单的优化想法,比如空间换时间,记录求过的边界并利用,但在最坏样例下还是O(n^2)的,还是不行。

    题目的解法是采用一个栈,非常的巧妙。

    维护一个栈;

    当遍历到位置的高度大于栈顶高度时: 压栈,同时说明了,此时这个位置的前一位的下标即为这个高度的左边界;(满足向左数第一个小于他的)

    当遍历到位置的高度小于栈顶高度时:一直弹栈至上述条件不满足,同时对每一个弹出的元素,他的右边界即为当前遍历到的位置(右数第一个大于他的)。

    此时可以根据左右边界计算以此高度能组成的最大直方图面积。

    可以直接在栈中存储下标,便于计算边界差值(左边界是栈内部的下一个元素,因为只要能压栈,说明前一个即为其左边界),同时也方便取出某一下标的高度。

    注意:栈为空时,下标取-1;

    代码:

     1 class Solution {
     2 public:
     3     int largestRectangleArea(vector<int>& heights) {
     4         int result = 0;
     5         int sz = heights.size(); 
     6         stack<int> s;
     7         for (int i = 0; i < sz; ++i) {
     8             if (s.empty() || heights[i] >= heights[s.top()]) {
     9                 s.push(i);
    10             }
    11             else {
    12                 while (!s.empty() && heights[s.top()] > heights[i]) {
    13                     int cur = s.top();
    14                     s.pop();
    15                     int prev = (s.empty()) ? -1 : s.top();
    16                     result = max(result, (i - prev - 1) * heights[cur] );
    17                 }
    18                 s.push(i);
    19             }
    20         }
    21         while (!s.empty()) {
    22             int cur = s.top();
    23             s.pop();
    24             int prev = (s.empty()) ? -1 : s.top();
    25             result = max(result, (sz - prev - 1) * heights[cur] );
    26         }
    27         return result;
    28     }
    29 };
     
  • 相关阅读:
    MT4编程初级手册
    导出oracle序列
    Win10下用Anaconda安装TensorFlow
    06-python opencv 使用摄像头捕获视频并显示
    python @修饰符的几种用法
    Ubuntu 16.04 安装 PyCharm
    Python判断变量的数据类型的两种方法
    上海地图
    kindle看扫描版pdf的解决办法
    查看已安装tensorflow版本
  • 原文地址:https://www.cnblogs.com/wangxiaobao/p/5958411.html
Copyright © 2011-2022 走看看