Bootstrap

代码随想三刷单调栈篇1

739. 每日温度

题目

链接

代码

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        int[] res = new int[temperatures.length];
        Deque<Integer> stack = new LinkedList();
        for(int i =0;i<temperatures.length;i++){
            if(stack.isEmpty()){
                stack.addLast(i);
                continue;
            }
            int tempIndex = stack.getLast();
            if(temperatures[i]<temperatures[tempIndex]){
                stack.addLast(i);
                continue;
            }
            while(!stack.isEmpty()&&temperatures[(tempIndex = stack.getLast())]<temperatures[i]){
                res[tempIndex] = i-tempIndex;
                stack.removeLast();
            }
            stack.addLast(i);
        }
        return res;
    }
}

496. 下一个更大元素 I

题目

链接

代码

class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        int[] arr = new int[nums1.length];
        Arrays.fill(arr,-1);
        Deque<Integer> stack = new LinkedList();
        for(int i =0;i<nums2.length;i++){
            if(stack.isEmpty()){
                stack.addLast(i);
                continue;
            }
            int tempIndex = stack.getLast();
            if(nums2[i]<nums2[tempIndex]){
                stack.addLast(i);
                continue;
            }
            while(!stack.isEmpty()&&nums2[(tempIndex = stack.getLast())]<nums2[i]){
                for(int j=0;j<nums1.length;j++){
                    if(nums1[j]==nums2[tempIndex]){
                        arr[j] = nums2[i];
                    }
                }
                stack.removeLast();
            }
            stack.addLast(i);
        }
        return arr;
    }
}

503. 下一个更大元素 II

题目

链接

代码

class Solution {
    public int[] nextGreaterElements(int[] nums) {
        int[] result = new int[nums.length];
        Arrays.fill(result,-1);
        Deque<Integer> stack = new LinkedList();
        for(int i =0;i<nums.length*2;i++){
            int index = i%nums.length;
            if(stack.isEmpty()){
                stack.addLast(index);
                continue;
            }
            int tempIndex = stack.getLast();
            if(nums[index]<nums[tempIndex]){
                stack.addLast(index);
                continue;
            }
            while(!stack.isEmpty()&&nums[(tempIndex = stack.getLast())]<nums[index]){
                result[tempIndex] = result[tempIndex]==-1?nums[index]:result[tempIndex];
                stack.removeLast();
            }
            stack.addLast(index);
        }
        return result;
    }
}

42. 接雨水

题目

链接

代码

class Solution {
    public int trap(int[] height) {
       int size = height.length;

        if (size <= 2) return 0;

        // in the stack, we push the index of array
        // using height[] to access the real height
        Stack<Integer> stack = new Stack<Integer>();
        stack.push(0);

        int sum = 0;
        for (int index = 1; index < size; index++){
            int stackTop = stack.peek();
            if (height[index] < height[stackTop]){
                stack.push(index);
            }else if (height[index] == height[stackTop]){
                // 因为相等的相邻墙,左边一个是不可能存放雨水的,所以pop左边的index, push当前的index
                stack.pop();
                stack.push(index);
            }else{
                //pop up all lower value
                int heightAtIdx = height[index];
                while (!stack.isEmpty() && (heightAtIdx > height[stackTop])){
                    int mid = stack.pop();

                    if (!stack.isEmpty()){
                        int left = stack.peek();

                        int h = Math.min(height[left], height[index]) - height[mid];
                        int w = index - left - 1;
                        int hold = h * w;
                        if (hold > 0) sum += hold;
                        stackTop = stack.peek();
                    }
                }
                stack.push(index);
            }
        }

        return sum;
    }
}

84. 柱状图中最大的矩形

题目

链接

代码

class Solution {
    public int largestRectangleArea(int[] heights) {
        Stack<Integer> st = new Stack<Integer>();
        
        // 数组扩容,在头和尾各加入一个元素
        int [] newHeights = new int[heights.length + 2];
        newHeights[0] = 0;
        newHeights[newHeights.length - 1] = 0;
        for (int index = 0; index < heights.length; index++){
            newHeights[index + 1] = heights[index];
        }

        heights = newHeights;
        
        st.push(0);
        int result = 0;
        // 第一个元素已经入栈,从下标1开始
        for (int i = 1; i < heights.length; i++) {
            // 注意heights[i] 是和heights[st.top()] 比较 ,st.top()是下标
            if (heights[i] > heights[st.peek()]) {
                st.push(i);
            } else if (heights[i] == heights[st.peek()]) {
                st.pop(); // 这个可以加,可以不加,效果一样,思路不同
                st.push(i);
            } else {
                while (heights[i] < heights[st.peek()]) { // 注意是while
                    int mid = st.peek();
                    st.pop();
                    int left = st.peek();
                    int right = i;
                    int w = right - left - 1;
                    int h = heights[mid];
                    result = Math.max(result, w * h);
                }
                st.push(i);
            }
        }
        return result;
    }
}
;