单调栈练习

12 篇文章 0 订阅
2 篇文章 0 订阅
文章介绍了使用单调栈解决两个LeetCode问题的方法:接雨水问题和寻找最大的矩形面积。优化后的暴力解法通过两次遍历降低复杂度,而单调栈按行计算避免了重复计算,提高了效率。另一个问题中,单调栈用于找到histogram中最大的矩形面积。
摘要由CSDN通过智能技术生成

单调栈

接雨水

题目链接:https://leetcode.cn/problems/trapping-rain-water/

暴力

针对每一列求出左右最高的列,然后利用其中相对小的那一个进行计算

优化思路:针对每一列求出,中间有重复计算,因此遍历2轮,分别计算左边最高和右边最高,降低复杂度

class Solution {
    public int trap(int[] height) {
        int[] left = new int[height.length];
        int[] right = new int[height.length];
        int max = 0;
        for (int i = 0;i< height.length;i++){
            left[i] = max;
            max = Math.max(max,height[i]);
        }
        max = 0;
        for (int i = height.length-1;i>=0;i--){
            right[i] = max;
            max = Math.max(max,height[i]);
        }
        int count = 0;
        for (int i = 0;i< height.length;i++){
            int h = Math.min(left[i],right[i] );
            if (h>height[i]) count+= h-height[i];
        }
        return count;
    }
}

单调栈

按行计算

class Solution {
    public int trap(int[] height) {
        Deque<Integer> d = new LinkedList<>();
        int count = 0;
        for (int i = 0;i< height.length;i++){
            while(!d.isEmpty()&&height[d.getLast()]<height[i]){
                int index = d.removeLast();
               if (d.isEmpty()){
                   continue;
               }else {
                   int left = d.getLast();
                   int h = Math.min(height[left],height[i] )-height[index];
                   count += h*(i-left-1);
               }
            }
            while(!d.isEmpty()&&height[d.getLast()]==height[i]){
                d.removeLast();
            }
            d.addLast(i);
        }
        return count;
    }
}

最大的矩形

题目连接:https://leetcode.cn/problems/largest-rectangle-in-histogram

递增栈

class Solution {
    public int largestRectangleArea(int[] heights) {
        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];
        }

        Deque<Integer> d = new LinkedList<>();
        int max = 0;
        for (int i = 0;i< newHeights.length;i++){
            while (!d.isEmpty()&&newHeights[d.getLast()]> newHeights[i]){
                int index = d.removeLast();
                int len = i - d.getLast()-1;
                max = Math.max(max,len*newHeights[index]);
            }
            d.addLast(i);
        }
        return max;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值