算法day42-单调栈(2)

目录

  1. 接雨水
  2. 柱状图中的最大矩形

一、接雨水

https://leetcode.cn/problems/trapping-rain-water/?envType=problem-list-v2&envId=8At1GmaZ

方法一:前后缀

class Solution {
    public int trap(int[] height) {
        int n = height.length;
        int[] preMax = new int[n];
        preMax[0] = height[0];
        for(int i=1; i<n; i++){
            preMax[i] = Math.max(preMax[i-1], height[i]);
        }
        int[] sufMax = new int[n];
        sufMax[n-1] = height[n-1];
        for(int i=n-2; i>=0; i--){
            sufMax[i] = Math.max(sufMax[i+1], height[i]);
        }
        int ans = 0;
        for(int i=0; i<n; i++){
            ans += Math.min(preMax[i], sufMax[i]) - height[i];
        }
        return ans;
    }
}

方法二:单调栈

class Solution {
    public int trap(int[] height) {
        int length = height.length;
        Deque<Integer> stack = new LinkedList<>();
        if(length <= 2) return 0;
        stack.push(0);
        int res = 0;
        for(int i=1; i<length; i++){
            int stackTop = stack.peek();
            int curHeight = height[i];        //当前的高度
            if(height[i] < height[stackTop]){
                stack.push(i);
            }else if(height[i] == height[stackTop]){
                stack.pop();
                stack.push(i);
            }else{
                while(!stack.isEmpty() && curHeight > height[stackTop]){
                    int mid = stack.pop();         //前一个元素,比当前元素小的
                    if(!stack.isEmpty()){
                        int prev = stack.peek();
                        int h = Math.min(height[prev], curHeight) - height[mid];
                        int w = i - prev - 1;
                        int s = h*w;
                        if(s > 0) res += s;
                        stackTop = stack.peek();
                    }
                }
                stack.push(i);      //把原本大的那个元素还是要压入栈,维护单调栈
            }
        }
        return res;
    }
}

 

 二、柱状图中的最大矩形

https://leetcode.cn/problems/largest-rectangle-in-histogram/description/?envType=problem-list-v2&envId=8At1GmaZ

 

import java.util.Deque;
import java.util.LinkedList;

class Solution {
    public int largestRectangleArea(int[] heights) {
        Deque<Integer> stack = new LinkedList<>();
        int maxArea = 0;
        int n = heights.length;
        
        for (int i = 0; i <= n; i++) {
            // 当前柱子的高度,如果是最后一个位置,设为0以触发清算
            int h = (i == n) ? 0 : heights[i];
            
            // 如果当前柱子高度小于栈顶柱子的高度,开始清算栈中比当前高的柱子
            while (!stack.isEmpty() && h < heights[stack.peek()]) {
                int height = heights[stack.pop()]; // 弹出栈顶柱子的高度
                // 计算宽度:如果栈为空,宽度是i;否则是i - 新栈顶 - 1
                int width = stack.isEmpty() ? i-0+1-1 : i - stack.peek() - 1;
                maxArea = Math.max(maxArea, height * width);
            }
            stack.push(i); // 将当前柱子索引入栈
        }
        
        return maxArea;
    }
}

 

posted @ 2025-06-17 14:21  筱倩  阅读(246)  评论(0)    收藏  举报