题意:

image.png

解题思路:

  1. 思路:单调栈
  2. 1. 维护一个单调栈,如果当前柱形条 i 的高度比栈顶要低,则栈顶元素 cur 出栈;
  3. 出栈后,cur 右边第一个比它低的柱形条就是 i,左边第一个比它低的柱形条是当前栈中的 top
  4. 2. 计算topi直接的宽度差 * 当前的cur高度;
  5. 3. 继续出下一个栈,比如1452,先计算[452] = 5后还的计算[1452] = 8的值;
  6. 4. 不断出栈直到栈为空或者柱形条 i 不再比 top 低;
  7. 5. 继续下一轮i入栈;
  8. 注意:
  9. array_push($heights, -1);//避免都是递增,在末尾加一个最小值

PHP代码实现:

  1. class Solution {
  2. /**
  3. * @param Integer[] $heights
  4. * @return Integer
  5. */
  6. function largestRectangleArea($heights) {
  7. //避免都是递增,在末尾加一个最小值
  8. array_push($heights, -1);
  9. $stack = new SplStack;
  10. $max = 0;
  11. for ($i = 0; $i < count($heights); $i++) {
  12. //遍历到下一个节点比当前元素小
  13. while (!$stack->isEmpty() && $heights[$stack->top()] >= $heights[$i]) {
  14. $last = $stack->pop();
  15. if (!$stack->isEmpty()) {
  16. $width = $i - $stack->top() - 1;
  17. } else {
  18. $width = $i;
  19. }
  20. $max = max($max, $heights[$last] * $width);
  21. }
  22. $stack->push($i);
  23. }
  24. return $max;
  25. }
  26. function largestRectangleArea1($heights) {
  27. if (empty($heights) || count($heights) == 0) return 0;
  28. $max = 0;
  29. $n = count($heights);
  30. for ($i = 0; $i < $n; ++$i) {
  31. $l = $i;
  32. $r = $i;
  33. while ($l >= 0 && $heights[$l] >= $heights[$i]) --$l;
  34. while ($r < $n && $heights[$r] >= $heights[$i]) ++$r;
  35. $max = max($max, $heights[$i] * ($r - $l - 1));
  36. }
  37. return $max;
  38. }
  39. }

GO代码实现:

  1. func largestRectangleArea(heights []int) int {
  2. if len(heights) == 0 {
  3. return 0
  4. }
  5. stack := make([]int, 0)
  6. max := 0
  7. for i := 0; i <= len(heights); i++ {
  8. cur := 0
  9. if i != len(heights) {
  10. cur = heights[i]
  11. }
  12. // 当前高度小于栈,则将栈内元素都弹出计算面积
  13. for len(stack) != 0 && cur <= heights[stack[len(stack)-1]] {
  14. pop := stack[len(stack)-1]
  15. stack = stack[:len(stack)-1]
  16. h := heights[pop]
  17. // 计算宽度
  18. w := i
  19. if len(stack) != 0 {
  20. peek := stack[len(stack)-1]
  21. w = i - peek - 1
  22. }
  23. max = Max(max, h*w)
  24. }
  25. stack = append(stack, i)
  26. }
  27. return max
  28. }
  29. func Max(a, b int) int {
  30. if a > b {
  31. return a
  32. }
  33. return b
  34. }