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;
    }
}
相关推荐
yi0116 小时前
LeetCode 219:存在重复元素 II——哈希表记录“最近一次出现的位置”
数据结构·人工智能·笔记·python·算法·leetcode·哈希表
灯澜忆梦8 小时前
【面向对象编程C++】| 基础语法
java·c++·算法
禾小西9 小时前
Redis 数据结构:快速的 Redis 有哪些慢操作?
数据结构·数据库·redis
小蒋观天下9 小时前
专项方案:大场景港口AI安防、多干扰环境下的算法调优与落地实操
人工智能·深度学习·算法·安全·机器学习·计算机视觉·ai大模型
Evand J9 小时前
【电机滤波例程5】渐消因子自适应扩展卡尔曼滤波(EKF),MATLAB。PMSM负载突变下的状态估计。附下载链接
算法·matlab
H.莓飛9 小时前
【数据结构】二叉树_OJ题
linux·开发语言·数据结构·算法
好想像大佬一样能够ak所有10 小时前
Leetcode35.搜索插入位置
数据结构·算法·leetcode
aqiu11111110 小时前
【C++算法打怪专栏】LeetCode 165. 比较版本号(双指针与字符串流法)
c++·算法·leetcode
黄金龙PLUS10 小时前
如何基于置换算法来设计对称加密算法
算法·网络安全·密码学·哈希算法·同态加密
不会就选b10 小时前
算法日常・每日刷题--<动态规划>14
算法