返回轨道
算法 · 2026-05-14 · 22 阅读

P146 直方图中的最大矩形

算法 22 阅读

信号摘要

难度:Hard · 时长:10:29 · leetcode 84 · lintcode 122

P146 直方图中的最大矩形

未对外公开播放权限
点击查看说明

描述

这个题目说的是,给你一个非负整数数组,数组中的整数表示直方图的高度,每个直方图的宽度都为 1,你要计算出直方图中最大矩形的面积。

比如说,给你的数组是 2, 1, 3, 4, 1, 它对应的直方图如图所示:
      +--+
      |  |
   +--+  |
   |  |  |

+--+ | | | | | | | | | +--+ | +--+ | | | | | | +--+--+--+--+--+--> 2 1 3 4 1

在这些直方图组成的区域里,可以形成的最大矩形是 3 和 4 这两个直方图中,高度为 3,宽度为 2 的矩形。它的面积为 6,因此你要返回 6。

代码

public class AlgoCasts {

  // Time: O(n^2), Space: O(1)
  public int largestRectangleAreaExpand(int[] heights) {
    if (heights == null || heights.length == 0) return 0;
    int max = 0, n = heights.length;
    for (int i = 0; i < n; ++i) {
      int l = i, r = i;
      while (l >= 0 && heights[l] >= heights[i]) --l;
      while (r < n && heights[r] >= heights[i]) ++r;
      max = Math.max(max, heights[i] * (r - l - 1));
    }
    return max;
  }

  // Time: O(n), Space: O(n)
  public int largestRectangleAreaStack(int[] heights) {
    if (heights == null || heights.length == 0) return 0;
    int max = 0, n = heights.length;
    Stack<Integer> st = new Stack<>();
    for (int r = 0; r <= n; ++r) {
      int h = r == n ? 0 : heights[r];
      while (!st.empty() && h < heights[st.peek()]) {
        int idx = st.pop();
        int l = st.empty() ? -1 : st.peek();
        max = Math.max(max, heights[idx] * (r - l - 1));
      }
      st.push(r);
    }
    return max;
  }

  // 用数组模拟栈
  // Time: O(n), Space: O(n)
  public int largestRectangleAreaArray(int[] heights) {
    if (heights == null || heights.length == 0) return 0;
    int max = 0, n = heights.length, top = -1;
    int[] st = new int[n+1];
    for (int r = 0; r <= n; ++r) {
      int h = r == n ? 0 : heights[r];
      while (top != -1 && h < heights[st[top]]) {
        int idx = st[top--];
        int l = top == -1 ? -1 : st[top];
        max = Math.max(max, heights[idx] * (r - l - 1));
      }
      st[++top] = r;
    }
    return max;
  }

}

📡 通讯频道