day50 单调栈

单调栈的整体的运用范围: 要保留遍历过元素的状态的时候。

问题1:每日温度

题目:

https://leetcode.cn/problems/daily-temperatures/description/

思路:

最关键的问题:是啥单调栈 递增还是递减

这个如何判断呢 就是看我要比较的 比如说我拿到一个温度 我要去看看 之后比他高的温度对吧 所以啥 应该放递增栈

代码:

java 复制代码
class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        Deque<Integer> stack = new LinkedList<>();
        int res[] = new int[temperatures.length];
        stack.push(0);
        for(int i = 1; i < temperatures.length; i++){
            // 循环对比
            while(!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]){
                res[stack.peek()] = i - stack.peek();
                stack.pop();
            }
            // 如果是空的话 那就添加
            stack.push(i);
        }
    return res;
    }
}
问题2:下一个更大的元素I

题目:

https://leetcode.cn/problems/next-greater-element-i/

思路:

在问题1的基础上加了一个映射

代码:

java 复制代码
class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        Deque<Integer> stack = new LinkedList<>();
        int res[] = new int[nums1.length];
        // 借用hashmap存放nums[1]的映射
        HashMap<Integer,Integer> map = new HashMap<>();
        for(int i = 0; i < nums1.length; i++) res[i] = -1; 
        for(int i = 0; i < nums1.length; i++) map.put(nums1[i],i);
        stack.push(0);
        for(int i = 1; i < nums2.length; i++){
            while(!stack.isEmpty() && nums2[stack.peek()] < nums2[i]){
                if(!map.containsKey(nums2[stack.peek()])){
                    stack.pop();
                }else{
                    res[map.get(nums2[stack.peek()])] = nums2[i];
                    stack.pop();
                }
            }
            stack.push(i);
            }
        return res;
    }
}
问题3:下一个更大的元素II

题目:

https://leetcode.cn/problems/next-greater-element-ii/description/

思路:

在问题2的基础之上 加了个循环的条件 遇见循环考虑用numsi%len 一个新的思路

代码:

java 复制代码
class Solution {
    public int[] nextGreaterElements(int[] nums) {
        Deque<Integer> stack = new LinkedList<>();
        int len = nums.length;
        int res[] = new int [len];
        for(int i = 0; i < len; i++) res[i] = -1;
        stack.push(0);
        for(int i = 1; i < len*2; i++){
            while(!stack.isEmpty() && nums[stack.peek()] < nums[i%len]){
                res[stack.peek()] = nums[i%len];
                stack.pop();
            }
            stack.push(i%len);
        }
        return res;
    }
}
问题4:接雨水

题目:

https://leetcode.cn/problems/trapping-rain-water/description/

思路:

在前三道题的基础之上 这里维护的是一个区间

left

right

mid

弄清楚这三个

代码:

java 复制代码
class Solution {
    public int trap(int[] height) {
        if(height.length <=2){
            return 0;
        }
        Stack<Integer> stack = new Stack<>();
        int res = 0;
        stack.push(0);
        for(int i = 1; i < height.length; i++){
            if(height[i] < height[stack.peek()]){
                stack.push(i);
            }else if(height[i] == height[stack.peek()]){
                // 因为相等的相邻墙,左边一个是不可能存放雨水的,所以pop左边的index, push当前的index
                stack.pop();
                stack.push(i);
            }else{
                while(!stack.isEmpty() && height[i] > height[stack.peek()]){
                    // 先记录中间的 把移动放到上面
                    int mid = stack.pop();
                    if(!stack.isEmpty()){
                        int h = Math.min(height[i],height[stack.peek()])-height[mid];
                        int w = i - stack.peek()-1;
                        res += (h*w);
                    }
                }
                stack.push(i);
            }
        }
        return res;
    }
}
问题5:柱状图中的最大的矩形

题目:

https://leetcode.cn/problems/largest-rectangle-in-histogram/description/

思路:

在前三道题的基础之上 这里维护的是一个区间

left

right

mid

弄清楚这三个

其中这里的是单调递减栈

代码:

java 复制代码
class Solution {
    public int largestRectangleArea(int[] heights) {
        if(heights.length == 0){
            return 0;
        }
        // 增加哨兵
        int[] newheight = new int [heights.length + 2];
        newheight[0] = 0;
        newheight[heights.length + 1] = 0;
        for(int i = 0; i < heights.length; i++){
            newheight[i+1] = heights[i];
        }
        // 单调栈的模版题
        Deque<Integer> stack = new LinkedList<>();
        int maxArea = 0;
        stack.push(0);
        for(int i = 0; i < newheight.length; i++){
            if(newheight[i] > newheight[stack.peek()]){
                stack.push(i);
            }else if(newheight[i] == newheight[stack.peek()]){
                stack.pop();
                stack.push(i);
            }else{
                while(!stack.isEmpty() && newheight[i] < newheight[stack.peek()]){
                    int mid = stack.peek();
                    stack.pop();
                    if(!stack.isEmpty()){
                        int left = stack.peek();
                        int right= i;
                        int h = newheight[mid];
                        int w = right - left -1;
                        maxArea = Math.max(maxArea,h*w);
                    }
                }
                stack.push(i);
            }
        }
        return maxArea;
    }
}
相关推荐
Tongzhi20261 天前
考勤数据本地化存储:通芝科技无感考勤一体机的数据安全逻辑
大数据·数据结构·科技·均值算法·数据库开发·推荐算法
她说可以呀1 天前
Spring-ai-Rag-多文件格式生成 List<Document>
数据结构·list
饼饼学习空间智能1 天前
遥操作数据能否提升机器人自主化水平?详解模仿学习、仿真放大与Sim2Real闭环
人工智能·算法
间歇性努力持续性发呆的野生快乐选手1 天前
dfs回溯,bfs枚举,完全背包
c++·算法·深度优先·宽度优先
郝学胜_神的一滴1 天前
干货版《算法导论》17:双数极值配对与卡牌手牌编码最优解
数据结构·算法
nike0good1 天前
Codeforces Round 1101 (Div. 2) 题解
算法
中年阿甘1 天前
解析式布局-二次线长布局
线性代数·算法·矩阵
程序喵大人1 天前
【C++进阶】STL算法与函数对象 -【C++进阶】STL算法与函数对象
开发语言·c++·算法
我不会插花弄玉1 天前
10.list【由浅入深-C++】
数据结构·c++·list
星轨初途1 天前
LeetCode 热题 100——day6 三数之和
数据结构·c++·算法·leetcode·职场和发展