代码学习记录45---单调栈

随想录日记part45

t i m e : time: time: 2024.04.17



主要内容:今天开始要学习单调栈的相关知识了,今天的内容主要涉及:每日温度 ;下一个更大元素 I



Topic1每日温度

题目:

思路:

通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时我们就要想到可以用单调栈了。

用一个栈来记录我们遍历过的元素,因为我们遍历数组的时候,我们不知道之前都遍历了哪些元素,以至于遍历一个元素找不到是不是之前遍历过一个更小的,所以我们需要用一个容器(这里用单调栈)来记录我们遍历过的元素。

在使用单调栈的时候首先要明确如下几点:

1.单调栈里存放的元素是什么?

单调栈里只需要存放元素的下标i就可以了,如果需要使用对应的元素,直接Ti就可以获取。

2.单调栈里元素是递增呢? 还是递减呢?

注意以下讲解中,顺序的描述为 从栈头到栈底的顺序

如果求一个元素右边第一个更大元素,单调栈就是递增的,如果求一个元素右边第一个更小元素,单调栈就是递减的。
文字描述理解起来有点费劲,接下来我画了一系列的图,来讲解单调栈的工作过程,大家再去思考,本题为什么是递增栈。

使用单调栈主要有三个判断条件。

  • 当前遍历的元素Ti小于栈顶元素Tst.top()的情况
  • 当前遍历的元素Ti等于栈顶元素Tst.top()的情况
  • 当前遍历的元素Ti大于栈顶元素Tst.top()的情况

用temperatures = 73, 74, 75, 71, 71, 72, 76, 73为例来逐步分析,输出应该是 1, 1, 4, 2, 1, 1, 0, 0:

1.首先先将第一个遍历元素加入单调栈:

加入T1 = 74,因为T1 > T0(当前遍历的元素Ti大于栈顶元素Tst.top()的情况)。我们要保持一个递增单调栈(从栈头到栈底),所以将T0弹出,T1加入,此时result数组可以记录了,result0 = 1,即T0右面第一个比T0大的元素是T1

加入T2,同理,T1弹出:

加入T3,T3 < T2 (当前遍历的元素Ti小于栈顶元素Tst.top()的情况),加T3加入单调栈。

加入T4,T4 == T3 (当前遍历的元素Ti等于栈顶元素Tst.top()的情况),此时依然要加入栈,不用计算距离,因为我们要求的是右面第一个大于本元素的位置,而不是大于等于!

加入T5,T5 > T4 (当前遍历的元素Ti大于栈顶元素Tst.top()的情况),将T4弹出,同时计算距离,更新result:

T4弹出之后, T5 > T3 (当前遍历的元素Ti大于栈顶元素Tst.top()的情况),将T3继续弹出,同时计算距离,更新result:

直到发现T5小于Tst.top(),终止弹出,将T5加入单调栈:

加入T6,同理,需要将栈里的T5,T2弹出

同理,继续弹出

此时栈里只剩下了T6

加入T7, T7 < T6 直接入栈,这就是最后的情况,result数组也更新完了。

代码实现如下:

java 复制代码
import java.util.Stack;

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

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



Topic2下一个更大元素 I

思路:

接下来就要分析如下三种情况,一定要分析清楚。

情况一:当前遍历的元素Ti小于栈顶元素Tst.top()的情况

此时满足递增栈(栈头到栈底的顺序),所以直接入栈。

情况二:当前遍历的元素Ti等于栈顶元素Tst.top()的情况

如果相等的话,依然直接入栈,因为我们要求的是右边第一个比自己大的元素,而不是大于等于!

情况三:当前遍历的元素Ti大于栈顶元素Tst.top()的情况

此时如果入栈就不满足递增栈了,这也是找到右边第一个比自己大的元素的时候。

判断栈顶元素是否在nums1里出现过,(注意栈里的元素是nums2的元素),如果出现过,开始记录结果。

记录结果这块逻辑有一点小绕,要清楚,此时栈顶元素在nums2数组中右面第一个大的元素是nums2i(即当前遍历元素)。

java 复制代码
class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        int[] result = new int[nums1.length];
        Arrays.fill(result, -1);
        Stack<Integer> stack = new Stack<>();
        HashMap<Integer, Integer> umap = new HashMap<>(); // key:下标元素,value:下标
        for (int i = 0; i < nums1.length; i++) {
            umap.put(nums1[i], i);
        }
        stack.push(0);
        for (int i = 1; i < nums2.length; i++) {
            if (nums2[i] <= nums2[stack.peek()]) {
                stack.push(i);
            } else {
                while (!stack.isEmpty() && nums2[i] > nums2[stack.peek()]) {
                    if (umap.containsKey(nums2[stack.peek()])) {
                        Integer index = umap.get(nums2[stack.peek()]);
                        result[index] = nums2[i];
                    }
                    stack.pop();
                }
                stack.push(i);
            }
        }
        return result;
    }
}

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

相关推荐
05664612 分钟前
RAG 向量检索:从“查字“到“查意“
数据库·人工智能·学习·oracle
却道天凉_好个秋34 分钟前
音视频学习(一百零二):全彩夜视
学习·音视频·全彩夜视
0566461 小时前
agent学习Day23——文件上传与 Embedding 语义检索
python·学习·embedding
小白说大模型1 小时前
【MYSQL】MYSQL学习的一大重点:索引(下)- B+树
b树·学习·mysql
却道天凉_好个秋1 小时前
音视频学习(一百零一):IR-Cut
学习·音视频·ir-cut
森诺Alyson1 小时前
前沿技术借鉴研讨-2026.8.6(影响中国育龄妇女生育偏好的因素/分孕周血压与不良妊娠结局的风险)
论文阅读·经验分享·学习·论文笔记
若无情我 纸小铭1 小时前
Nginx学习笔记(二) Nginx--connection&request
笔记·学习·nginx
paopaokaka_luck2 小时前
基于springboot3+vue3的云南本土影视文旅推荐平台(协同过滤算法、Echarts图形化分析)
前端·spring boot·学习·算法·echarts·mybatis
paopaokaka_luck12 小时前
基于springboot3+vue3的企业考勤管理系统(部门树递归、Echarts图形化分析)
开发语言·spring boot·学习·echarts·mybatis·需求分析·代码规范
minglie112 小时前
zynq高频小数据量PS闭环 抖动时间的测量
学习