代码随想录Day63

42.接雨水

题目:42. 接雨水 - 力扣(LeetCode)

思路:两边比中间的高,就能留住雨水,先下降,再上升,取边界中小的作为水位线,从小的一端遍历到另一端减1的位置,就是水量,取值不知道怎么取

尝试(有想法,但是不全)
class Solution {
    public int trap(int[] height) {
        int len = height.length;
        int[] stack = new int[len];
        int res = 0;
        Stack<Integer> stack = new Stack<>();
        int temp = 0;
        int popNum = 0;
        for(int i =0; i<len; i++){
            while(!stack.isEmpty()&&height[i]>stack.peek()){
                temp+=stack.pop();
                popNum++;
            }
            stack.push(height[i]);
        }
    }
}
答案
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.柱状图中最大的矩形

题目:84. 柱状图中最大的矩形 - 力扣(LeetCode)

思路:取出非递减的数字,构成矩形 

答案
class Solution {
    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;
    }
}
小结
  • 以第 i 个柱子为高度,往两边扩展,找到左右两边比自己矮的,确定矩形的长度,得到矩形面积 
  • 我:先找到比较高的柱子
  • 卡尔:挨个遍历柱子,计算result(以该柱子为高的矩形面积),用max取出最大
  • 数组头部加入0,考虑【8,6,4,2】的情况,如果数组前面没有0,8入栈之后,遍历到6要进行计算时,不足三个元素(left,mid,right),无法得到结果
  • 数组尾部加入0,考虑【2,4,6,8】的情况,入栈之后是  8,6,4,2】,找不到比栈口元素小的数字,无法触发计算,因此末尾要加上0
  • ❗关键:挨个将柱子作为高,朝两边扩展,得到矩形
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值