leetcode 739, 84, 42, 901 (Monotonic Stack)

If a problem is suitable to use the monotonic stack, it must have at least three characters:

  1. It is a “range queries in an array” problem.
  2. The minima/maxima element or the monotonic order of elements in a range is useful to get the answer to every range query.
  3. When an element is popped from the monotonic stack, it will never be used again.

 

Solution for leetcode 739 

https://leetcode.com/problems/daily-temperatures/

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        int n = temperatures.length;
        Stack<Integer> stack = new Stack();
        int[] output = new int[n];
        for(int i = n - 1; i >= 0; i--){
            while(!stack.isEmpty() && temperatures[stack.peek()] <= temperatures[i]){
                    stack.pop();
            }
            if(stack.isEmpty()){
                output[i] = 0;  
            }
            else{
                output[i] = stack.peek() - i;
            }
            stack.add(i);
        }
        return output;
    }
}

Thoughts on leetcode 84

https://leetcode.com/problems/largest-rectangle-in-histogram/

For a height at index i, if we can find its left and right boundaries, we can find its area. By maintaining a monotonic stack, we can find the left and right boundaries when we pop elements from the stack. (it's very important to understand the characteristics)

Solution for leetcode 84

https://leetcode.com/problems/largest-rectangle-in-histogram/

class Solution {
    public int largestRectangleArea(int[] heights) {
        Stack<Integer> stack = new Stack();
        int maxArea = Integer.MIN_VALUE;
        //calculate the area when iterating through the heights array
        for(int i = 0; i < heights.length; i++){
            while(!stack.isEmpty() && heights[stack.peek()] > heights[i]){
                int height = heights[stack.pop()];
                int left = stack.isEmpty()? -1 : stack.peek();      
                int width = i - left - 1;       
                int area = height * width;    
                maxArea = area > maxArea ? area : maxArea;

            }
            stack.add(i);
        }
        //calculate the remaining area when poping the element from the stack
        //the right boundary of the remaining elements in the stack is the end
        while(!stack.isEmpty()){
            int height = heights[stack.pop()];
            int left = stack.isEmpty()? -1 : stack.peek();
            int right = heights.length;
            int width = right - left - 1;
            int area = height * width;
            maxArea = area > maxArea ? area : maxArea;
          
        }
        return maxArea;
    }
}

Thoughts on leetcode 42 

https://leetcode.com/problems/trapping-rain-water/

Solution for leetcode 42

class Solution {
    public int trap(int[] height) {
        Stack<Integer> stack = new Stack();
        int rain = 0;
        for(int i = 0; i < height.length; i++){
            while(!stack.isEmpty() && height[stack.peek()] <= height[i]){
                int low = height[stack.pop()];
                if(!stack.isEmpty()){
                    int prev = height[stack.peek()];
                    int tall = Math.min(prev, height[i]) - low;
                    int width = i - stack.peek() -1;
                    rain += tall * width;
                }
            }
            stack.add(i);
        }
        return rain;
    }
}

Solution for leetcode 901 

https://leetcode.com/problems/online-stock-span/

class StockSpanner {
    Stack<Integer> stack;
    ArrayList<Integer> arr;
    int cur = -1;

    public StockSpanner() {
        stack = new Stack();
        arr = new ArrayList();
    }
    
    public int next(int price) {
        if(stack.isEmpty() || arr.get(stack.peek()) > price){
            cur++;
            stack.add(cur);
            arr.add(price);
            return 1;
        }
        else{
             while(!stack.isEmpty() && arr.get(stack.peek()) <= price){
                stack.pop();
            }
            cur++;
            int prev = stack.isEmpty()? -1 : stack.peek();
            int output = cur - prev;
            stack.add(cur);
            arr.add(price);
            return output;           
        }  
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值