1. 概述

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩形的最大面积。

84. ***柱状图中最大的矩形 - 图1

图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。

1.1 思路

创建一个递增栈,遇到小栈就求一次栈内元素最大面积。

2. 解题

  1. <?php
  2. class Solution
  3. {
  4. /**
  5. * @param Integer[] $heights
  6. * @return Integer
  7. */
  8. public function largestRectangleArea($heights)
  9. {
  10. if (!$heights) return 0;
  11. $n = count($heights);
  12. $increaseStack = new SplStack();
  13. // 通过递增栈来确定 左边界
  14. $rightMargin = $leftMargin = [];
  15. for ($i = 0; $i < $n; $i++) {
  16. while (!$increaseStack->isEmpty() && $heights[$increaseStack->top()] >= $heights[$i]) {
  17. $increaseStack->pop();
  18. }
  19. $leftMargin[$i] = $increaseStack->isEmpty() ? -1 : $increaseStack->top();
  20. $increaseStack->push($i);
  21. }
  22. // 通过递增栈来确定 右边界
  23. $reduceStack = new SplStack();
  24. for ($j = $n - 1; $j >= 0; $j--) {
  25. while (!$reduceStack->isEmpty() && $heights[$reduceStack->top()] >= $heights[$j]) {
  26. $reduceStack->pop();
  27. }
  28. $rightMargin[$j] = $reduceStack->isEmpty() ? $n : $reduceStack->top();
  29. $reduceStack->push($j);
  30. }
  31. // 计算最大矩形
  32. $answer = 0;
  33. for ($i = 0; $i < $n; $i++) {
  34. echo ($rightMargin[$i] - $leftMargin[$i] - 1) * $heights[$i] . "\t";
  35. $answer = max($answer, ($rightMargin[$i] - $leftMargin[$i] - 1) * $heights[$i]);
  36. }
  37. return $answer;
  38. }
  39. }
  40. // $heights = [2,1,5,6,2,3];
  41. $heights = [5, 6, 5, 6, 5, 6, 5, 6, 5, 6];
  42. $cls = new Solution();
  43. $ret = $cls->largestRectangleArea($heights);
  44. echo "\n" . $ret . "\n";