【算法基础】2.1栈和队列(单调栈和单调队列)

news/2024/5/19 19:14:30/文章来源:https://blog.csdn.net/qq_43406895/article/details/131726991

文章目录

  • 例题
    • 3302. 表达式求值(栈的应用)😭😭😭😭😭
    • 830. 单调栈
      • 知识点
      • 解法
    • 154. 滑动窗口 (单调队列)
      • 知识点
      • 解法
  • 相关链接 & 相关题目

例题

3302. 表达式求值(栈的应用)😭😭😭😭😭

https://www.acwing.com/activity/content/problem/content/3648/
在这里插入图片描述

import java.util.*;public class Main {// 存储数字的栈static Deque<Integer> numStk = new LinkedList<>();// 存储运算符号的栈static Deque<Character> opStk = new LinkedList<>();public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String s = scanner.next();// 各个运算符的优先级字典Map<Character, Integer> pr = Map.of('+', 1, '-', 1, '*', 2, '/', 2);for (int i = 0; i < s.length(); ++i) {char ch = s.charAt(i);// 如果是数字,直接放入栈里if (Character.isDigit(ch)) {int x = 0, j = i;while (j < s.length() && Character.isDigit(s.charAt(j))) {x = x * 10 + (s.charAt(j) - '0');++j;}i = j - 1;numStk.push(x);} else if (ch == '(') opStk.push(ch);   // 左括号直接放入栈里else if (ch == ')') {                   // 出现右括号,一直计算到出现左括号while (opStk.peek() != '(') eval();opStk.pop();    // 把'('弹出来} else {            // 是运算符号,检查和上个运算符号之间的优先级关系如何,先算优先级大的while (!opStk.isEmpty() && opStk.peek() != '(' && pr.get(opStk.peek()) >= pr.get(ch)) eval();opStk.push(ch);}}while (!opStk.isEmpty()) eval();    // 把剩下的运算符都计算了System.out.println(numStk.peek());}static void eval() {// 取出两个数字和一个运算符进行运算int b = numStk.pop(), a = numStk.pop();char ch = opStk.pop();int x;if (ch == '+') x = a + b;else if (ch == '-') x = a - b;else if (ch == '*') x = a * b;else x = a / b;numStk.push(x);}
}

这题思路有难度,代码也很长。

使用栈来解决这个问题。


  • 遇到数字时,直接将数字放入栈中。
  • 遇到 ( 时,也直接放入栈中。
  • 遇到 ) 时,进行计算知道栈顶是 ( 。
  • 遇到运算符时,和当前在栈顶的运算符进行比较,先计算优先级高的运算符。

830. 单调栈

https://www.acwing.com/activity/content/problem/content/867/

在这里插入图片描述

知识点

单调栈 可以用来求取 数组中每一个元素 左右两边 第一个比它大或者第一个比它小的位置在哪里

解法

为了求每个数字左边第一个比它小的数字,需要使用一个单调栈。

这个单调栈从栈底到栈顶是单调递减的。

当枚举到一个元素时,从栈顶开始检查,如果栈顶的元素比当前元素小,那就找到了当前元素左边第一个更小的元素;
如果栈顶的元素 >= 当前的元素,那么就将其弹出栈。

如果栈是空的,说明左侧没有比当前元素更小的元素了。

import java.util.*;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();Deque<Integer> stk = new ArrayDeque<>();for (int i = 0; i < n; ++i) {int x = scanner.nextInt();while (!stk.isEmpty() && x <= stk.peek()) stk.pop();if (!stk.isEmpty()) System.out.print(stk.peek() + " ");else System.out.print("-1 ");stk.push(x);}}
}

154. 滑动窗口 (单调队列)

https://www.acwing.com/activity/content/problem/content/868/
在这里插入图片描述

知识点

单调队列常常用来维护一个窗口中当前的最大值或者最小值。

注意单调队列要使用 双端队列 来实现。

解法

使用两个双端队列分别维护当前窗口中的最大值和最小值。

和单调栈类似,每次枚举到一个新的元素时,将该元素一直与队列中的最后一个元素相比较,保持队列的单调性。

每个窗口的最大值和最小值就是队列队首的元素。

记得要及时移除窗口之外的元素。

import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.*;public class Main {public static void main(String[] args) throws IOException {Scanner sin = new Scanner(new BufferedInputStream(System.in));BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));int n = sin.nextInt(), k = sin.nextInt();int[] a = new int[n], max = new int[n - k + 1], min = new int[n - k + 1];Deque<Integer> dqMax = new ArrayDeque<>(), dqMin = new ArrayDeque<>();for (int i = 0; i < n; ++i) {a[i] = sin.nextInt();while (!dqMax.isEmpty() && a[dqMax.peekLast()] <= a[i]) dqMax.pollLast();dqMax.offerLast(i);while (dqMax.peekFirst() + k <= i) dqMax.pollFirst();while (!dqMin.isEmpty() && a[dqMin.peekLast()] >= a[i]) dqMin.pollLast();dqMin.offerLast(i);while (dqMin.peekFirst() + k <= i) dqMin.pollFirst();if (i >= k - 1) {max[i - k + 1] = a[dqMax.peekFirst()];min[i - k + 1] = a[dqMin.peekFirst()];}}for (int i = 0; i < n - k + 1; ++i) bw.write(min[i] + " ");bw.write("\n");for (int i = 0; i < n - k + 1; ++i) bw.write(max[i] + " ");bw.flush();sin.close();bw.close();}
}

相关链接 & 相关题目

碰撞类问题是栈的经典应用场景:【算法】行星碰撞&机器人碰撞(栈的使用)
贡献法经常需要使用单调栈来找到左右两端的边界:【算法】贡献法相关题目练习

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于weka手工实现多层感知机(BPNet)

一、BP网络 1.1 单层感知机 单层感知机&#xff0c;就是只有一层神经元&#xff0c;它的模型结构如下1&#xff1a; 对于权重 w w w的更新&#xff0c;我们采用如下公式&#xff1a; w i w i Δ w i Δ w i η ( y − y ^ ) x i (1) w_iw_i\Delta w_i \\ \Delta w_i\eta(y…

RabbitMQ 同样的操作一次成功一次失败

RabbitMQ 是一个功能强大的消息队列系统&#xff0c;广泛应用于分布式系统中。然而&#xff0c;我遇到这样的情况&#xff1a;执行同样的操作&#xff0c;一次成功&#xff0c;一次失败。在本篇博文中&#xff0c;我将探讨这个问题的原因&#xff0c;并提供解决方法。 我是在表…

创作一周年纪念日【道阻且长,行则将至】

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; 技术之外的往事 &#x1f383;所处时段&#xff1a; 大学生涯[1/2] 文章目录 一、起点一切皆有定数 二、成果尽心、尽力 三、相遇孤举者难起&#xff0c;众行者易趋 四、未来长风破浪会有时&#xff0c;直挂云…

markdown2html 转化流程

定义一个extensions function markedMention() {return {extensions: [{name: mention,level: inline,start(src) {// console.log("markedMention start....", src);return src.indexOf(#)},tokenizer(src, tokens) {const rule /^(#[a-zA-Z0-9])\s?/const match…

JMeter websocket接口测试

前言 在一个网站中&#xff0c;很多数据需要即时更新&#xff0c;比如期货交易类的用户资产。在以前&#xff0c;这种功能的实现一般使用http轮询&#xff0c;即客户端用定时任务每隔一段时间向服务器发送查询请求来获取最新值。这种方式的弊端显而易见&#xff1a; 有可能造…

解决Gson解析json字符串,Integer变为Double类型的问题

直接上代码记录下。我代码里没有Gson包&#xff0c;用的是nacos对Gson的封装&#xff0c;只是包不同&#xff0c;方法都一样 import com.alibaba.nacos.shaded.com.google.common.reflect.TypeToken; import com.alibaba.nacos.shaded.com.google.gson.*;import java.util.Map;…

idea-控制台输出乱码问题

idea-控制台输出乱码问题 现象描述&#xff1a; 今天在进行IDEA开发WEB工程调式的时候控制台日志输出了乱码&#xff0c;如下截图 其实开发者大多都知道乱码是 编码不一致导致的&#xff0c;但是有时候就是不知到哪些地方不一致&#xff0c;今天我碰到的情况可能和你的不相同…

前端框架Layui实现动态表格效果用户管理实例(对表格进行CRUD操作-附源码)

目录 一、前言 1.什么是表格 2.表格的使用范围 二、案例实现 1.案例分析 ①根据需求找到文档源码 ②查询结果在实体中没有该属性 2.dao层编写 ①BaseDao工具类 ②UserDao编写 3.Servlet编写 ①R工具类的介绍 ②Useraction编写 4.jsp页面搭建 ①userManage.jsp ②…

Docker基础——初识Docker

Docker架构 Docker 使用客户端-服务器 (C/S) 架构模式&#xff0c;使用远程API来管理和创建Docker容器。 Docker 客户端(Client) : Docker 客户端通过命令行或者其他工具使用 Docker SDK (https://docs.docker.com/develop/sdk/) 与 Docker 的守护进程通信。Docker 主机(Host…

搭建微服务工程 【详细步骤】

一、准备阶段 &#x1f349; 本篇文章用到的技术栈 mysqlmybatis[mp]springbootspringcloud alibaba 需要用到的数据库 订单数据库: SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0;-- ---------------------------- -- Table structure for shop_order -- --------------…

windows下配置pytorch + yolov8+vscode,并自定义数据进行训练、摄像头实时预测

最近由于工程需要&#xff0c;研究学习了一下windows下如何配置pytorch和yolov8&#xff0c;并自己搜集数据进行训练和预测&#xff0c;预测使用usb摄像头进行实时预测。在此记录一下全过程 一、软件安装和配置 1. vscode安装 windows平台开发python&#xff0c;我采用vscod…

Docker架构

目录 Docker总架构图Docker ClientDocker DaemonDocker ServerDocker EngineJob Docker RegistryGraphDriverGraphDriverNetworkDriverExecDriver LibcontainerDocker Container Docker可以帮助用户在容器内部快速自动化部署应用&#xff0c;并利用Linux内核特性命名空间&#…

uniapp微信小程序使用axios(vue3+axios+ts版)

版本号 "vue": "^3.2.45", "axios": "^1.4.0", "axios-miniprogram-adapter": "^0.3.5", 安装axios及axios适配器&#xff0c;适配小程序 yarn add axios axios-miniprogram-adapter 使用axios 在utils创建utils/…

二、学习回归 - 基于广告费预测点击量

山外风雨三尺剑 有事提剑下山去 云中花鸟一屋书 无忧翻书圣贤来 1.设置问题 以Web广告和点击量的关系为例来学习回归。 前提&#xff1a;投入的广告费越多&#xff0c;广告的点击量就越高。 根据以往的经验数据&#xff0c;可以得到下图&#xff1a; 那么假设我要投200块的广…

NFTScan 与 Decert 达成合作伙伴,双方在 NFT 数据方面展开合作

近日&#xff0c;NFT 数据基础设施 NFTScan 与 Decert 达成合作伙伴关系&#xff0c;双方在多链 NFT 数据层面展开合作。在 Decert 产品中&#xff0c;由 NFTScan 为其提供专业的多链 NFT 数据支持&#xff0c;为用户带来优质的 NFT 搜索查询等相关交互功能&#xff0c;提升用户…

IDEA的火焰图简单使用

1. 火焰图是什么&#xff1f; 简单来说就是用来查看程序耗时的一张图 如何读懂火焰图&#xff1f; 2. mac上如何生成火焰图 找了一圈&#xff0c;原来idea原本就支持… 3. 测试代码 package org.example;import java.util.ArrayList; import java.util.List; import java.…

Git超级详细使用

一、概述 1.1 、git工作流程 命令如下&#xff1a; 1. clone (克隆):从远程仓库中克隆代码到本地仓库 2. checkout(检出) :从本地仓库中检出一个仓库分支然后进行修订add &#xff08;添加):在提交前先将代码提交到暂存区 3. commit(提交)︰提交到本地仓库。本地仓库中保存修…

怎么修复vcruntime140_1.dll缺失,vcruntime140_1.dll丢失的解决方案

vcruntime140_1.dll是什么&#xff1f; vcruntime140_1.dll是Windows操作系统中的一个动态链接库文件&#xff0c;它属于Microsoft Visual C Redistributable的一部分。这个文件包含了一些在运行使用了C语言编写的程序时所需的函数和资源。当系统无法找到或加载vcruntime140_1…

Deepin/UOS 装机 手动安装 分区 注意事项

以下3个分区必须 efi 分区 boot 分区 / (根) 分区 我们下期见&#xff0c;拜拜&#xff01;

mac批量修改文件名为不同名字

mac批量修改文件名为不同名字怎么弄&#xff1f;很多小伙伴通过私信向我求助&#xff0c;用什么方法可以在mac电脑上批量修改文件名称&#xff0c;将大量文件修改成不同的名称。这可能是一项比较麻烦的操作&#xff0c;在电脑上进行过批量重命名的小伙伴都知道&#xff0c;一般…