代码随想录算法训练营第58天 | ● 739. 每日温度 ● 496.下一个更大元素 I

2023-09-21 10:53:56

文章目录


前言

单调栈;


一、739. 每日温度

单调栈的本质是空间换时间,因为在遍历的过程中需要用一个栈来记录右边第一个比当前元素高的元素,优点是整个数组只需要遍历一次。

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

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

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

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

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

注意以下讲解中,顺序的描述为 从栈头到栈底的顺序,因为单纯的说从左到右或者从前到后,不说栈头朝哪个方向的话,大家一定比较懵。

这里我们要使用递增循序(再强调一下是指从栈头到栈底的顺序),因为只有递增的时候,栈里要加入一个元素i的时候,才知道栈顶元素在数组中右面第一个比栈顶元素大的元素是i。

 

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

  • 当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况
  • 当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况
  • 当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况

把这三种情况分析清楚了,也就理解透彻了

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;
    }
}

二、496.下一个更大元素 I

这么定义这个result数组初始化应该为多少呢?

题目说如果不存在对应位置就输出 -1 ,所以result数组如果某位置没有被赋值,那么就应该是是-1,所以就初始化为-1。

在遍历nums2的过程中,我们要判断nums2[i]是否在nums1中出现过,因为最后是要根据nums1元素的下标来更新result数组。

注意题目中说是两个没有重复元素 的数组 nums1 和 nums2

没有重复元素,我们就可以用map来做映射了。根据数值快速找到下标,还可以判断nums2[i]是否在nums1中出现过。

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

  1. 情况一:当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况

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

  1. 情况二:当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况

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

  1. 情况三:当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况

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

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

 

 

class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        Stack<Integer> temp = new Stack<>();
        int[] res = new int[nums1.length];
        Arrays.fill(res,-1);
        HashMap<Integer,Integer> hashMap = new HashMap<>();
        for(int i = 0;i<nums1.length;i++){
            hashMap.put(nums1[i],i);
        }
        temp.add(0);
        for(int i =1;i<nums2.length;i++){
            if(nums2[i] <= nums2[temp.peek()]){
                temp.add(i);
            }else{
                while(!temp.isEmpty() && nums2[temp.peek()]<nums2[i]){
                    if(hashMap.containsKey(nums2[temp.peek()])){
                        Integer index = hashMap.get(nums2[temp.peek()]);
                        res[index] = nums2[i];
                    }
                    temp.pop();
                }
                temp.add(i);
            }
        }
        return res;
    }
}


总结

单调栈;

更多推荐

正则表达式基础

正则表达式是一种用来匹配字符串的技术,它可以通过特定的模式来搜索、替换或提取字符串中的内容。正则表达式的语法有很多不同的标记和修饰符,以下是一些常见的基础语法代码:\d:匹配任意一个数字。\w:匹配任意一个字母或数字。\s:匹配任意一个空白字符。.:匹配除换行符以外的任意一个字符。[abc]:匹配字符集合中的任意一个字

RocketMQ概论

目录前言:1.概述2.下载安装、集群搭建3.消息模型4.如何保证吞吐量4.1.消息存储4.1.1顺序读写4.1.2.异步刷盘4.1.3.零拷贝4.2.网络传输前言:RocketMQ的代码示例在安装目录下有全套详细demo,所以本文不侧重于讲API这种死的东西,而是侧重于讲解RocketMQ的特性。消息中间件无非需要关注

OJ练习第173题——单词接龙 II

单词接龙II力扣链接:126.单词接龙II题目描述按字典wordList完成从单词beginWord到单词endWord转化,一个表示此过程的转换序列是形式上像beginWord->s1->s2->…->sk这样的单词序列,并满足:每对相邻的单词之间仅有单个字母不同。转换过程中的每个单词si(1<=i<=k)必须是字典

算法通关村 | 透彻理解动态规划

1.斐波那契数列1,1,2,3,5,8,13,.....f(n)=f(n-1)+f(n-2)代码实现publicstaticintcount_2=0;publicintfibonacci(intn){if(n<=2){count_2++;returnn;}intf1=1;intf2=2;intsum=0;for(int

Redis主从复制(Redis6.2.5版本)

1、Redis单击服务问题?Redis的单机服务在实际的应用中会有很多的问题,所以在实际的使用中如果使用了redis服务,往往都不是单机服务,都会配置主从复制或者哨兵机制及redis的集群服务等。Redis的单机服务,当主机发生机器故障的时候,我们就需要做数据迁移,同时也会大概率出现数据大量都是的情况,并且短时间内,系

ChatGPT:解释Java中 ‘HttpResponse‘ 使用 ‘try-with-resources‘ 的警告和处理 ‘Throwable‘ 打印警告

ChatGPT:解释Java中‘HttpResponse’使用‘try-with-resources’的警告和处理‘Throwable’打印警告我在IDEA中对一个函数的警告点击了ignore,怎么撤回这个呢ChatGPT:要撤回在IDEA中对一个函数的警告的忽略,您可以按照以下步骤进行操作:打开您的项目,并在编辑器中

SkyWalking快速上手(三)——架构剖析2

文章目录介绍UI组件什么是UI组件?UI组件的配置配置UI组件示例使用SkyWalkingUIStorage组件什么是Storage组件?Storage组件的配置配置Storage组件示例结语介绍接上篇文章:SkyWalking快速上手(二)——架构剖析1SkyWalking是一个开源的分布式系统追踪、监控和诊断工具,

Python爬虫:通过js逆向获取某视频平台上的视频的m3u8链接

Python爬虫:通过js逆向获取某视频平台上的视频的m3u8链接1.前言2.js逆向分析3.参考代码和运行结果1.前言现在我们在网页端看的视频,其前端实现原理就小编目前知道的而言,总的有两点:其一,直接就是一个mp4(或其他类似的)视频链接,如果我们能得到这个视频链接,直接用这个链接就能下载到这个视频;其二,和第一点

毕业设计|基于stm32单片机的app视频遥控抽水灭火小车设计

基于stm32单片机的app视频遥控抽水灭火水泵小车设计1、项目简介1.1系统构成1.2系统功能2、部分电路设计2.1L298N电机驱动电路设计2.2继电器控制电路设计3、部分代码展示3.1小车控制代码3.1水泵控制代码4演示视频及代码资料获取1、项目简介视频简介中包含资料https://www.bilibili.co

自定义协议、序列化与反序列化

在编写TCP和UDP程序的时候,我们很自然的就使用了读取的函数对数据进行获取,对于UDP来说提供的是无连接的以数据报的形式进行传输,对于TCP来说是面向数据流的,在之前的程序中我们只是进行了读取的操作,但是并没有对读取的内容进行分析。那如果我们要传输一些结构化的数据的话,那么就需要引入"协议"这个概念。网络版计算器在本

前后端分离毕设项目之产业园区智慧公寓管理系统设计与实现(内含源码+文档+教程)

博主介绍:✌全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久,选择我们就是选择放心、选择安心毕业✌🍅由于篇幅限制,想要获取完整文章或者源码,或者代做,拉到文章底部即可看到个人VX。🍅2023年-2024年最新计算机毕业设计本科选题大全汇总感兴趣的可以先收藏

热文推荐