单调栈算法,可以维持栈内保持单调递增或者递减,不符合的弹出栈进行处理,局部最大值可知。

例子 1 最大矩形 【根据概念-边界补零】

image.png

细节

1.已知结论 第i个矩形面积最大时出现在左右两边第1个小于其高度的矩形围成的面积。【符合单调栈的特性】
2.因为是遇到小的才弹出,所以前后要设置最小值,需要前一个和后一个,所以第一个和最后一个需要满足通式,因此前后个补了0.

  1. class Solution {
  2. public int largestRectangleArea(int[] heights) {
  3. int len = heights.length;
  4. Stack<Integer> stack = new Stack<>();
  5. int[] arr = new int[len+2];
  6. System.arraycopy(heights,0,arr,1,heights.length);
  7. int res = 0;
  8. for(int i = 0;i < len+2;i ++){
  9. while(!stack.isEmpty() && arr[stack.peek()] > arr[i]){
  10. int pop = stack.pop();
  11. if(stack.isEmpty()) break;
  12. int l = stack.peek();
  13. int c = i - l - 1;
  14. int k = arr[pop];
  15. res = Math.max(res,c*k);
  16. }
  17. stack.push(i);
  18. }
  19. return res;
  20. }
  21. }

例子2 接雨水

image.png
image.png

  1. class Solution {
  2. public int trap(int[] height) {
  3. int len = height.length;
  4. LinkedList<Integer> stack = new LinkedList<>();
  5. int count = 0;
  6. for(int i = 0;i < len;i ++){
  7. while(!stack.isEmpty() && height[stack.peek()] < height[i]){
  8. int pop = stack.pop();
  9. if(stack.isEmpty()) break;
  10. int l = stack.peek();
  11. int c = i - l - 1;
  12. int k = Math.min(height[l],height[i]);
  13. count += c * (k - height[pop]);
  14. }
  15. stack.push(i);
  16. System.out.println(stack);
  17. }
  18. return count;
  19. }
  20. }