• 困难
  • 中等
  • 简单

    题目描述

    给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
    求在该柱状图中,能够勾勒出来的矩形的最大面积。
    84. 柱状图中最大的矩形 - 图1
    以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]。
    84. 柱状图中最大的矩形 - 图2
    图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。

来源,leetcode 每日一题 84. 柱状图中最大的矩形

例如:

  1. 输入: [2,1,5,6,2,3]
  2. 输出: 10

解题思路

  1. 暴力方法:以每个柱子为左边界,向右边探查可围成的最大矩形面积。

    1. class Solution {
    2. public:
    3. int largestRectangleArea(vector<int>& heights) {
    4. int s = 0;
    5. for (int i = 0; i < heights.size(); i++) {
    6. int height = heights[i];
    7. int width = 1;
    8. s = max(s, height * width);
    9. for (int j = i + 1; j < heights.size(); j++) {
    10. if (heights[j] < height) {
    11. height = heights[j];
    12. }
    13. width += 1;
    14. s = max(s, height * width);
    15. }
    16. }
    17. return s;
    18. }
    19. };

    上述为84. 柱状图中最大的矩形 - 图3的复杂度,导致时间超限。

  2. 优化

    1. 单调栈

      https://leetcode-cn.com/problems/largest-rectangle-in-histogram/solution/zhu-zhuang-tu-zhong-zui-da-de-ju-xing-by-leetcode-/


    2. 代码

      1. class Solution {
      2. public:
      3. int largestRectangleArea(vector<int>& heights) {
      4. int n = heights.size();
      5. vector<int> left(n), right(n);
      6. stack<int> mono_stack;
      7. for (int i = 0; i < n; ++i) {
      8. while (!mono_stack.empty() && heights[mono_stack.top()] >= heights[i]) {
      9. mono_stack.pop();
      10. }
      11. left[i] = (mono_stack.empty() ? -1 : mono_stack.top());
      12. mono_stack.push(i);
      13. }
      14. mono_stack = stack<int>();
      15. for (int i = n - 1; i >= 0; --i) {
      16. while (!mono_stack.empty() && heights[mono_stack.top()] >= heights[i]) {
      17. mono_stack.pop();
      18. }
      19. right[i] = (mono_stack.empty() ? n : mono_stack.top());
      20. mono_stack.push(i);
      21. }
      22. int ans = 0;
      23. for (int i = 0; i < n; ++i) {
      24. ans = max(ans, (right[i] - left[i] - 1) * heights[i]);
      25. }
      26. return ans;
      27. }
      28. };