单调栈的应用

  • 可以解决 求数组元素左边第一个大于其的元素
  • 接雨水 leetcode 42

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/trapping-rain-water
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    private int res = 0;
   public int trap(int[] height) {
       if(height.length == 0||height.length == 1||height.length == 2){
           return 0;
       }
       LinkedList<Integer> stack = new LinkedList<>();
       for(int i = 0;i<height.length;i++){
           int val = height[i];
           
           while(!stack.isEmpty() && val>height[stack.peek()]){
               int curIdex = stack.peek();
               //弹出栈顶元素 若栈顶有多个相等对应值的元素 都弹出
               while(!stack.isEmpty()&&height[curIdex] == height[stack.peek()]){
                   stack.pop();
               }
               if(!stack.isEmpty()){
                    int h = Math.min(val,height[stack.peek()]) - height[curIdex];
                    int w = i - stack.peek()-1;
                    res += h*w;
               }
               
           }
           stack.push(i);
           
       }
       return res;
    }
  • leetcode 84

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

    private int max = Integer.MIN_VALUE;
    public int largestRectangleArea(int[] heights) {
        if(heights== null || heights.length == 0){
            return 0;
        }
        int[] leftSide = new int[heights.length];
        int[] rightSide = new int[heights.length];
        LinkedList<Integer> stack = new LinkedList<>();
        stack.push(-1);
        for(int i = 0;i<heights.length;i++){
            int tem =0;
            int val = heights[i];
            while((tem =stack.peek())>=0){
                if(heights[tem] >= val){
                    stack.pop();
                }else{
                    leftSide[i] = tem;
                    stack.push(i);
                    break;
                }
            }
            if(tem <0){
                leftSide[i] = tem;
                stack.push(i);
            }      
        }
        stack = new LinkedList<>();
        stack.push(heights.length);
        for(int i = heights.length -1;i>=0;i--){
            int tem =heights.length;
            int val = heights[i];
            while((tem =stack.peek())<heights.length){
                if(heights[tem] >= val){
                    stack.pop();
                }else{
                    rightSide[i] = tem;
                    stack.push(i);
                    break;
                }
            }
            if(tem >=heights.length){
                stack.push(i);
                rightSide[i] = tem;
            }      
        }
        for(int  i = 0;i<heights.length;i++){
            max = Math.max(max,heights[i]*(rightSide[i]-leftSide[i]-1));
        }
        return max;
        }

你可能感兴趣的:(算法)