Day 53 || 42. 接雨水 、84.柱状图中最大的矩形

42. 接雨水

题目链接: 力扣题目链接
思路:单调栈使用单调栈栈由栈顶向栈底递增,这样与之前单调栈相同也就是遇到大于当前栈顶就进行计算pop,核心代码在下方,只计算当前栈顶左右两个高度相对较小一方来计算高度,要减去挡圈栈顶的高度,乘以左右来两侧长度,因为可能有两个高度一样的入栈,不必担心因为这样的话计算面积的高度为零,这样会继续while循环。
while (!stack.isEmpty() && height[i] > height[stack.peek()]) {
     int h = height[stack.pop()];
     if (stack.isEmpty()) break; // 如果栈为空,则没有左边的边界
     int width = i - stack.peek() - 1;
     int minHeight = Math.min(height[stack.peek()], height[i]);
     sum += (minHeight - h) * width;
}

双指针方法左右两个指针,然后记录左右两侧最大值while循环比较左右两个指针那个小哪边小就修改哪边,如果当前左/右指针小于左/右的最大值就计算当前面积,如果大于就更新最大值以此类推直到左侧指针大于等于右侧指针结束。

class Solution {
    public int trap(int[] height) {
        if (height == null || height.length == 0) return 0;

        int left = 0, right = height.length - 1;
        int Max_l = 0, Max_r = 0;
        int sum = 0;
        
        while (left < right) {
            if (height[left] < height[right]) {
                if (height[left] >= Max_l) {
                    Max_l = height[left]; // 更新左边最大值
                } else {
                    sum += Max_l - height[left]; // 计算水量
                }
                left++; // 左指针向右移动
            } else {
                if (height[right] >= Max_r) {
                    Max_r = height[right]; // 更新右边最大值
                } else {
                    sum += Max_r - height[right]; // 计算水量
                }
                right--; // 右指针向左移动
            }
        }

        return sum;
    }
}

84.柱状图中最大的矩形

题目链接: 力扣题目链接
思路:这个和之前的“ 42. 接雨水 ”类似,但是单调栈是递增的而且面积计算的是柱状的面积,同时数组两端要各加一个0,需要避免整个排序就是递减和数组中最小的那个柱无法计算的情况。
class Solution {
    public int largestRectangleArea(int[] heights) {
        Stack<Integer> stack = new Stack<>();
        int res = 0;
        int[] height = new int[heights.length+2];
        height[0]=0;
        int j=1;
        for(int he : heights){
            height[j]=he;
            j++;
        }
        height[j]=0;
        for (int i = 0; i < height.length; i++) {
            while (!stack.isEmpty() && height[i] < height[stack.peek()]) {
                int l = stack.pop();
                int h = height[l];
                int width = i - stack.peek() - 1;
               
                res = Math.max(res,h* width);
            }
            stack.push(i);
        }
        
        return res;
    }
}

时间:2.5h

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值