算法日记day 45(单调栈之每日温度|接雨水)

news2024/11/25 14:53:18

一、每日温度

题目:

给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。

示例 1:

输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]

示例 2:

输入: temperatures = [30,40,50,60]
输出: [1,1,1,0]

示例 3:

输入: temperatures = [30,60,90]
输出: [1,1,0]

思路:

使用一个栈结构,将第一位元素的下标值0压入栈中,分有三种情况

第一种,如果之后遍历的元素值小于栈顶压入的元素,将该元素的下标压入栈中

第二种:如果遍历的元素等于栈顶元素,同样也不做操作,将该下标值压入栈中 

第三种,如果遍历的元素值大于栈顶元素,用该下标减去栈顶元素下标,并将栈顶元素弹出,继续用该元素与新的栈顶元素比较,如果小于等于,则压入栈,如果大于,重复第三步操作

代码:

public int[] dailyTemperatures(int[] temperatures) {
    int len = temperatures.length; // 获取温度数组的长度
    Deque<Integer> stack = new LinkedList<>(); // 创建一个栈,用于存储温度的索引
    int[] res = new int[len]; // 初始化结果数组,用于存储每一天的等待天数

    stack.push(0); // 将第一个元素的索引压入栈中

    for (int i = 1; i < len; 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; // 返回结果数组
}
  • len 是温度数组的长度。
  • stack 是一个栈,用于存储温度的索引。
  • res 是一个数组,用于存储每一天的等待天数。
  • 初始将第一个温度的索引 0 压入栈中。
  • 从第二天(索引 1)开始遍历温度数组。
  • 如果当前温度小于或等于栈顶索引对应的温度,将当前索引 i 压入栈中。
  • 当前温度大于栈顶索引对应的温度,计算等待天数。
  • 对栈中所有小于当前温度的索引进行处理:
    • 更新结果数组 res,计算从栈顶索引到当前索引 i 的天数差。
    • 移除栈顶元素。
  • 将当前索引 i 压入栈中,准备处理后续的温度。
  • 返回包含每一天的等待天数的数组 res

二、接雨水 

题目:

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

示例 1:

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 

示例 2:

输入:height = [4,2,0,3,2,5]
输出:9

思路:

用单调栈的结构,压入第一个元素的下标0,循环遍历判断后面的元素值与栈顶元素值比较

如果小于栈顶元素值,则压入栈内

如果等于则代替

如果大于,则取栈顶元素为中间值并弹出栈顶元素,将遍历的元素与新的栈顶元素值比较取较小者,减去中间值得到高度h,然后栈顶元素下标值减去当前遍历的元素下标值再减一得到宽度w,最后高×宽得到面积,并记录,重复上述操作,直到遍历结束

 

代码:

public int trap(int[] height) {
    int size = height.length; // 获取高度数组的长度
    if (size <= 2) // 如果柱状图的长度小于等于2,则无法存储雨水,直接返回0
        return 0;

    Stack<Integer> stack = new Stack<>(); // 创建一个栈,用于存储柱子的索引
    stack.push(0); // 将第一个柱子的索引压入栈中
    int sum = 0; // 用于累加存储的雨水量

    for (int i = 1; i < size; i++) { // 从第二个柱子开始遍历
        if (height[i] < height[stack.peek()]) { // 当前柱子比栈顶柱子矮,直接压入栈中
            stack.push(i);
        } else if (height[i] == height[stack.peek()]) { // 当前柱子与栈顶柱子等高,移除栈顶柱子
            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; // 计算水槽的宽度
                    int hold = h * w; // 计算当前水槽能存储的水量
                    if (hold > 0) // 确保计算结果为正值
                        sum += hold; // 累加水量到总和中
                }
            }
            stack.push(i); // 将当前柱子的索引压入栈中
        }
    }
    return sum; // 返回计算的总水量
}
  1. 初始化

    • size 是柱状图的长度。
    • stack 用于存储柱子的索引。
    • sum 用于累计计算的雨水量。
  2. 遍历柱状图

    • 从第二个柱子开始遍历。
    • 如果当前柱子比栈顶柱子矮,则将当前柱子的索引压入栈中。
    • 如果当前柱子与栈顶柱子等高,则移除栈顶柱子,并将当前柱子的索引压入栈中。
    • 如果当前柱子比栈顶柱子高,处理栈中所有比当前柱子矮的柱子,并计算存储的雨水量。
  3. 计算水量

    • 弹出栈顶柱子,将其作为水槽的底部。
    • 如果栈中还有柱子,则计算水的高度和水槽的宽度,并累加计算的水量。
  4. 返回结果

    • 返回存储的雨水总量 sum

今天的学习就到这里 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2063547.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基本数据类型 --- 浮点型

float的机器码表示&#xff1a; 一个float数据 (pow(-1, sign) fraction) * pow(2, exponent - 127) 由上图&#xff0c;可得&#xff1a; (pow(-1, sign) fraction) * pow(2, exponent - 127) ( 1 2^(-2) ) * pow(2, 124-127) 0.15625 其他文章&#xff1a; https://b…

Go第一个程序

package mainimport "fmt"func main() {str : "hello go"fmt.Println(str) }上述很简单&#xff0c;如何使用os包获取命令行参数呢&#xff1f; package mainimport ("fmt""os" )func main() {fmt.Println(os.Args)str : "hello…

typora激活流程

1.安装typora Typora中文官网&#xff1a;Typora 官方中文站 Typora官网&#xff1a;https://typora.io/releases/all 2.打开软件安装位置 找到路径Typora\resources\page-dist\static\js的js文件&#xff0c;使用记事本编辑打开 替换 CtrlF查找 e.hasActivated"true&…

python-逆序数(赛氪OJ)

[题目描述] 在一个排列中&#xff0c;如果一对数的前后位置与大小顺序相反&#xff0c;即前面的数大于后面的数&#xff0c;那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。比如一个元素个数为 4 的数列&#xff0c;其元素为 2,4,3,1&#xff0c;则 (2,…

ubuntu20 vmware硬盘空间不够,进行扩容,实操成功!

背景 在编译mysql源码之前只给虚拟机分配了20G的空间&#xff0c;但是实际编译过程中&#xff0c;发现很快20G空间就被用完了&#xff0c;于是需要对已分配空间的虚拟机进行扩容至50G。 如何进行扩容&#xff1f; 注意首先需要在extended那一块先resize&#xff0c;把unloca…

H3C M-LAG与双活网关接口结合应用场景实验

H3C M-LAG与双活网关接口结合应用场景实验 实验拓扑 ​​ 实验需求 此实验需要在模拟器中使用交换机型号 S6850SW3 为接入交换机,连接 PC1 在 VLAN 10,连接 PC2在 VLAN 20,SW3 双上行连接到两台核心交换机SW1 和 SW2 为核心交换机,配置 M-LAG,并作为 VLAN 10 和 VLAN 2…

《Cloud Native Data Center Networking》(云原生数据中心网络设计)读书笔记 -- 07数据中心的边缘

本章将帮助你回答以下问题 可以用哪些方式将 Clos 拓扑连接到外部网终?边缘部署路由协议的最佳实践是什么?企业应如何处理混合云中的连接? 连接模型 为什么要连接到外部世界? 数据中心连接到外部世界的原因很多。如果你要对外提供某种服务(例如搜索服务广告推荐系统或内…

C语言:深入理解文件操作

目录 1. 为什么使用文件&#xff1f; 2. 什么是文件&#xff1f; 2.1 程序文件 2.2 数据文件 2.3 文件名 3. 二进制文件和文本文件&#xff1f; 3.1测试代码&#xff1a; 4. 文件的打开和关闭 4.1 流和标准流 4.1.1 流 4.1.2 标准流 4.2 文件指针 4.3 文件的打开…

【刷题笔记】二叉树2

1 二叉树的层序遍历 上一期我们讲了关于二叉树的前序、中序以及后序遍历的相关内容。然而&#xff0c;还存在一种遍历方式&#xff0c;这种方式非常符合我们人类的正常思维&#xff0c;可以求解很多树相关的问题&#xff0c;比较暴力——二叉树的层序遍历。 二叉树的层序遍历与…

股票买卖的思路与代码

题目 1302&#xff1a;股票买卖 时间限制: 1000 ms 内存限制: 65536 KB 提交数:8660 通过数: 4290 【题目描述】 最近越来越多的人都投身股市&#xff0c;阿福也有点心动了。谨记着“股市有风险&#xff0c;入市需谨慎”&#xff0c;阿福决定先来研究一下简化版的股…

文华软件自动画线 参数自调 多空波段变色线(源码自取)

编写思路 想要随意输入一个点位&#xff0c;即可按照这个点位自动画线&#xff0c;此线可以多空变色&#xff0c;上下突破线时箭头提示并发出声音预警。 代码函数重点解析 A、DRAWSL 绘制直线&#xff08;段&#xff09;。 用法&#xff1a; DRAWSL(COND,DATA,SLOPE,LEN,E…

【OpenCV】111

1 新建项目 新建项目&#xff0c;路径不要出现中文 文件夹名称 添加解释器&#xff0c;添加本地解释器 这样就创建好了一个文件夹&#xff0c;然后像我这样一级一级向下分&#xff0c;细分文件夹

TinyC编译器5—词法分析

1.词法分析的基本概念 词法分析也称为分词&#xff0c;此阶段编译器从左向右扫描源文件&#xff0c;将其字符流扫描分割成一个个的词&#xff08;记号、token&#xff09;。所谓token&#xff0c;就是源文件中不可再进一步分割的一串字符&#xff0c;类似英语中的单词&#xf…

Transformer大模型在训练过程中所需的计算量

目录 简介计算需求参数与数据集的权衡计算成本的工程意义内存需求推理模型权重总推理内存训练模型参数优化器状态梯度激活值和批大小总训练内存分布式训练分片优化器3D 并行分片优化器 + 3D 并行参考简介 许多关于Transformer语言模型的基本且重要的信息都可以用相当简单的方式…

基于微信小程序的大用户心理咨询系统设计与实现---附源码99040

目录 1 绪论 1.1 研究背景 1.2研究现状 1.3论文结构与章节安排 2 基于微信小程序的大用户心理咨询系统设计与实现分析 2.1 可行性分析 2.2 系统功能分析 2.3 系统用例分析 2.4 系统流程分析 2.5本章小结 3 基于微信小程序的大用户心理咨询系统设计与实现总体设计 3.…

网站首页配置-记录部分错误

目录 错误问题1: 解决方案: 错误问题2: 解决方案&#xff1a; 错误问题3&#xff1a; 解决方案&#xff1a; 错误问题4&#xff1a; 解决方案&#xff1a; EL的作用: 错误问题1: 解决方案: 里面的代码写错&#xff0c;cateSecond应该写成categorySecond 错误问题2: 解…

toRef 与 toRefs

在 ref函数与reactive函数的对比 这一篇博文中&#xff0c;我们从使用角度对比了 ref 与 reactive 的区别&#xff0c;最终得出结论是&#xff0c; 通过 ref 定义的数据&#xff0c;在 js脚本中使用需要 xxx.value &#xff0c;在模板中会自动解包&#xff0c;可以直接使用通过…

WIN 10 添加右键菜单(VSCode 打开当前目录)

WIN 10 添加右键菜单&#xff08;VSCode 打开当前目录&#xff09; 前言最终效果操作步骤 前言 每次打开代码都需要先打开 VSCode&#xff0c;再选择最近打开的项目或者浏览打开项目&#xff0c;感觉比较难找。所以自己添加了右键命令。 最终效果 操作步骤 cmd 打开注册表 找…

20240821给飞凌OK3588-C的核心板刷Rockchip原厂的Buildroot并启动

20240821给飞凌OK3588-C的核心板刷Rockchip原厂的Buildroot并启动 2024/8/21 15:22 viewproviewpro-ThinkBook-16-G5-IRH:~/repo_RK3588_Buildroot20240508$ viewproviewpro-ThinkBook-16-G5-IRH:~/repo_RK3588_Buildroot20240508$ ./build.sh lunch 3. rockchip_rk3588_evb7_…

C++智能指针的用法(全)

一、智能指针概念 C/C 语言最为人所诟病的特性之一就是存在内存泄露问题&#xff0c;因此后来的大多数语言都提供了内置内存分配与释放功能&#xff0c;有的甚至干脆对语言的使用者屏蔽了内存指针这一概念。这里不置贬褒&#xff0c;手动分配内存与手动释放内存有利也有弊&…