单调栈:739.每日温度 + 42.接雨水 +84.柱状图中最大的矩形

739.每日温度 题目:

在这里插入图片描述

思路:

①暴力法:两个循环
②单调栈:用栈来存放数组下标
当栈为空或当前温度小于等于栈顶索引对应的温度时,入栈
否则,出栈,日期则等于i - stack.pop()

代码:

class Solution {
    public int[] dailyTemperatures(int[] T) {
        Stack<Integer> stack = new Stack<Integer>();
        int len = T.length;
        int[] ans = new int[len];
        for(int i = 0;i < len;i++){
            while(!stack.isEmpty() && T[i] > T[stack.peek()]){
                    ans[stack.peek()] = i - stack.peek();
                    stack.pop();
            }
            stack.push(i);
        }
        return ans;
    }
}

复杂度分析:

时间复杂度:O(n)
空间复杂度:O(n)

42.接雨水 题目

在这里插入图片描述

思路:

维护一个递减的栈
①遍历每一个高度
②栈不为空 && 当前高度 > 栈顶高度,弹出栈顶
③当前高度 == 栈顶高度时,弹出栈顶
④栈不为空时(说明两边均有界),计算当前块的容量
⑤压栈

代码:

class Solution {
    public int trap(int[] height) {
        Stack<Integer> stack= new Stack<Integer>();
        int len = height.length;
        int ans = 0;
        for(int i = 0;i < len;i++){
            int right = i;
            while(!stack.isEmpty() && height[i] > height[stack.peek()]){//栈不为空&&当前高度>栈顶高度,弹出栈顶
                int cur_index = stack.pop();
                while(!stack.isEmpty() && height[cur_index] == height[stack.peek()])//当前高度 == 栈顶高度,弹出栈顶,一个不留
                    stack.pop();
                if(!stack.isEmpty()){
                    int left = stack.peek();
                    ans += (Math.min(height[left],height[right]) - height[cur_index])*(right - left - 1);
                }
            }
            stack.push(i);
        }
        return ans;
    }
}

复杂度分析:

时间复杂度:O(n)
空间复杂度:O(n)

84.柱状图中最大的矩形 题目

在这里插入图片描述

思路:

①要找到包含第 i 个矩形的最大面积,就要分别找到小于第 i 个位置高度的左右两边高度,维护一个递增的单调栈,来确定左边界,右边界就是当前遍历到的矩形
Tips:在这组矩形的首尾各自加一个高度为0的矩形
左边的0是为了保证宽度计算不遗漏
右边的0是为了保证每个位置的最大矩阵面积都可以得到计算

代码:

class Solution {
    public int largestRectangleArea(int[] heights) {
        Stack<Integer> stack = new Stack<Integer>();
        int right,left,cur_height;
        int max_s = 0;
        int len = heights.length;
        int[] new_heights = new int[len + 2];
        for(int i = 1; i < len+1;i++){
            new_heights[i] = heights[i-1];
        }//首尾增加两个高度为0的矩形,尾部加0是为了保证每个位置的最大矩形面积都得到计算
        for(int i = 0;i < len+2;i++){
            while(!stack.isEmpty() && new_heights[stack.peek()] > new_heights[i]){//维护一个递增栈,高度相等的不再加入
                right = i;//确定右边界
                cur_height = new_heights[stack.peek()];
                stack.pop();
                left = stack.peek();//确定左边界,因为数组最左边为0,因此不担心栈为空
                max_s = Math.max(max_s,cur_height*(right-left-1));
            }
            stack.push(i);
        } 
        return max_s;

    }
}

复杂度分析:

时间复杂度:O(n)
空间复杂度:O(n)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值