代码随想录算法训练营 单调栈part01

一、每日温度

739. 每日温度 - 力扣(LeetCode)

从左到右除了最后一个数其他所有的数都遍历一次,最后一个数据对应的结果肯定是 0,就不需要计算。遍历的时候,每个数都去向后数,直到找到比它大的数,这其他数了几次就是对应的值。

public int[] dailyTemperatures(int[] T) {
    int length = T.length;
    int[] result = new int[length];

    for (int i = 0; i < length; i++) {
        int current = T[i];
        if (current < 100) {
            for (int j = i + 1; j < length; j++) {
                if (T[j] > current) {
                    result[i] = j - i;
                    break;
                }
            }
        }
    }

    return result;
}

//单调栈方法
class Solution {
 
    public int[] dailyTemperatures(int[] temperatures) {

        int lens=temperatures.length;
        int []res=new int[lens];


        /*
        如果当前遍历的元素 大于栈顶元素,表示 栈顶元素的 右边的最大的元素就是 当前遍历的元素,
        	所以弹出 栈顶元素,并记录
        	如果栈不空的话,还要考虑新的栈顶与当前元素的大小关系
        否则的话,可以直接入栈。
        注意,单调栈里 加入的元素是 下标。
        */


        Deque<Integer> stack=new LinkedList<>();
        stack.push(0);
        for(int i=1;i<lens;i++){

            if(temperatures[i]<=temperatures[stack.peek()]){
                stack.push(i);
            }else{
                while(!stack.isEmpty()&&temperatures[i]>temperatures[stack.peek()]){
                    res[stack.peek()]=i-stack.peek();
                    stack.pop();
                }
                stack.push(i);
            }
        }

        return  res;
    }

二、下一个更大元素 I

496. 下一个更大元素 I - 力扣(LeetCode)

一旦要求下一个更大的元素,就是用单调栈解!

思路:

我们可以先预处理 nums2,使查询 nums1 中的每个元素在 nums2中对应位置的右边的第一个更大的元素值时不需要再遍历 nums2。于是,我们将题目分解为两个子问题:

第 1 个子问题:如何更高效地计算 nums2中每个元素右边的第一个更大的值;

第 2 个子问题:如何存储第 1 个子问题的结果。

算法:

使用单调栈来解决第 1 个子问题。倒序遍历 nums2,并用单调栈中维护当前位置右边的更大的元素列表,从栈底到栈顶的元素是单调递减的。

具体地,每次我们移动到数组中一个新的位置 i,就将当前单调栈中所有小于 nums2[i] 的元素弹出单调栈,当前位置右边的第一个更大的元素即为栈顶元素,如果栈为空则说明当前位置右边没有更大的元素。随后我们将位置 i 的元素入栈。

class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        Deque<Integer> stack = new ArrayDeque<Integer>();
        for (int i = nums2.length - 1; i >= 0; --i) {
            int num = nums2[i];
            while (!stack.isEmpty() && num >= stack.peek()) {
                stack.pop();
            }
            map.put(num, stack.isEmpty() ? -1 : stack.peek());
            stack.push(num);
        }
        int[] res = new int[nums1.length];
        for (int i = 0; i < nums1.length; ++i) {
            res[i] = map.get(nums1[i]);
        }
        return res;
    }
}
相关推荐
亦梦亦醒乐逍遥19 分钟前
【C++基础】字符串/字符读取函数解析
java·c++·算法
捞鱼哲学家38 分钟前
【hot100】刷题记录(11)-搜索二维矩阵 II
数据结构·线性代数·算法·leetcode·矩阵
L_M_TY1 小时前
G1. Yunli‘s Subarray Queries (easy version)
算法·stl·滑动窗口·离线查询
查理零世2 小时前
【算法】回溯算法专题③ ——排列型回溯 python
python·算法·深度优先
利刃大大2 小时前
【数据结构与算法】九大排序算法实现详解
c语言·数据结构·c++·算法·排序算法
眼镜哥(with glasses)2 小时前
蓝桥杯python基础算法(2-1)——排序
数据结构·算法·蓝桥杯
qystca3 小时前
【16届蓝桥杯寒假刷题营】第2期DAY2
数据结构·c++·算法·深度优先·二分·爆搜
南宫生4 小时前
力扣动态规划-19【算法学习day.113】
java·学习·算法·leetcode·动态规划
和风化雨4 小时前
排序算法--插入排序
c语言·c++·算法·排序算法
被AI抢饭碗的人4 小时前
算法题(56):旋转链表
数据结构·算法·链表