当前位置: 首页 > news >正文

【LeetCode】剑指 Offer Ⅱ 第6章:栈(6道题) -- Java Version

题库链接:https://leetcode.cn/problem-list/e8X3pBZi/

在这里插入图片描述

类型题目解决方案
栈的应用剑指 Offer II 036. 后缀表达式模拟 + 栈 ⭐
剑指 Offer II 037. 小行星碰撞分类讨论 + 栈 ⭐
单调栈剑指 Offer II 038. 每日温度单调栈 ⭐
剑指 Offer II 039. 直方图最大矩形面积单调栈 ⭐
剑指 Offer II 040. 矩阵中的最大矩形矩阵转化直方图 + 单调栈 ⭐

栈:后入后出,所以栈的插入和删除操作都发生在栈顶;
Java 中 Stack 的常用操作:

  • push(e):元素 e 入栈;
  • pop():位于栈顶的元素出栈,并返回该元素;
  • peek():返回位于栈顶的元素,该元素不出栈;

1. 剑指 Offer II 036. 后缀表达式 – P93

根据 逆波兰表示法,求该后缀表达式的计算结果。
有效的算符包括 +、-、*、/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

1.1 模拟 + 栈 – O(n)(⭐)

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

🎈 注意:该题是通过栈来保存操作数,但不保存运算符,通过对运算符的判断从而进行数值的模拟计算。

class Solution {// Solution1:用栈存储,每当遇到运算符时,就从栈中弹出两个数进行计算后存入// Note:栈中只保存操作数,不保存运算符public int evalRPN(String[] tokens) {ArrayDeque<Integer> deque = new ArrayDeque<>();for (String token : tokens) {switch(token) {case "+":case "-":case "*":case "/":int num1 = deque.pop();int num2 = deque.pop();deque.push(caculate(num1, num2, token));break;default:  // 不是运算符,则入栈deque.push(Integer.parseInt(token));}}return deque.poll();  // 最后栈中只剩下最终结果}public int caculate(int a, int b, String operator) {switch(operator) {case "+":return a + b;case "-":return b - a;case "*":return b * a;case "/":return b / a;default:return 0;}}
}

在这里插入图片描述

2. 剑指 Offer II 037. 小行星碰撞 – P96

给定一个整数数组 asteroids,表示在同一行的小行星。
对于数组中的每一个元素,其绝对值表示小行星的大小,正负表示小行星的移动方向(正表示向右移动,负表示向左移动)。每一颗小行星以相同的速度移动。
找出碰撞后剩下的所有小行星。碰撞规则:两个行星相互碰撞,较小的行星会爆炸。如果两颗行星大小相同,则两颗行星都会爆炸。两颗移动方向相同的行星,永远不会发生碰撞。

2.1 分类讨论 + 栈 – O(n)(⭐)

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

class Solution {public int[] asteroidCollision(int[] asteroids) {ArrayDeque<Integer> deque = new ArrayDeque<>();for (int as : asteroids) {// 1. 栈非空,相向碰撞,保留大值while (!deque.isEmpty() && deque.peek() > 0 && deque.peek() < -as) {deque.pop();}// 2. 栈非空,相向碰撞,同归于尽if (!deque.isEmpty() && as < 0 && deque.peek() == -as) {deque.pop();}// 3. 同向 | 栈为空 ,则入栈else if (as > 0 || deque.isEmpty() || deque.peek() < 0) {deque.push(as);}}int[] res = new int[deque.size()];for (int i = res.length-1; i >= 0; i--) {res[i] = deque.pop();}return res;}
}

在这里插入图片描述

3. 剑指 Offer II 038. 每日温度 – P98

请根据每日 气温 列表 temperatures ,重新生成一个列表,要求其对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。如果气温在这之后都不会升高,请在该位置用 0 来代替。

3.1 单调栈 – O(n)(⭐)

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

关于单调栈的更多内容可参考:【华为机考】专题突破 第一周:单调栈 739 、503 、901、84
……
该题解中的栈存储的是元素的 下标

class Solution {// Solution1:单调栈public int[] dailyTemperatures(int[] temperatures) {int[] res = new int[temperatures.length];Stack<Integer> sk = new Stack<>();for (int i = 0; i < temperatures.length; i++) {// 如果栈非空,且当前气温大于栈顶气温,则计算等待天数,并弹出栈顶元素while (!sk.empty() && temperatures[i] > temperatures[sk.peek()]) {int index = sk.pop();res[index] = i - index; }// 顺序添加每个元素,不存在更大气温的元素会被永远存在栈中sk.push(i);}return res;}
}

在这里插入图片描述

4. 剑指 Offer II 039. 直方图最大矩形面积 – P100

给定非负整数数组 heights ,数组中的数字用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。

4.1 单调栈 – O(n)(⭐)

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

Key:每次计算的是某某高度下的矩形的最大面积。高为出栈元素高度,宽则为比该出栈元素小的两侧元素下标的差值。

class Solution {// Solution1:单调递增栈,栈中存储元素下标public int largestRectangleArea(int[] heights) {Stack<Integer> sk = new Stack<>();sk.push(-1);  // 初始下标int max = 0;for (int i = 0; i < heights.length; i++) {// 如果当前元素小于或等于栈顶元素,则让栈顶元素出栈,同时计算栈顶高度矩形的最大面积while (sk.peek() != -1 && heights[sk.peek()] >= heights[i]) {int h = heights[sk.pop()];int w = i - sk.peek() - 1;max = Math.max(max, h * w);}// 栈中元素始终保持单调递增sk.push(i);}while (sk.peek() != -1) {  // 计算栈中剩余元素高度矩形的最大面积int h = heights[sk.pop()];int w = heights.length - sk.peek() -1;max = Math.max(max, h * w);}return max;}
}

在这里插入图片描述

4.2 分治 – O(logn)

时间复杂度 O ( l o g n ) O(logn) O(logn),空间复杂度 O ( n ) O(n) O(n)

Key:将直方图的最大矩形分成了3种可能:1. 矩形通过最矮的柱子;2. 矩形的起始柱子和终止柱子都在最矮的柱子的左侧;3. 矩形的起始柱子和终止柱子都在最矮的柱子的右侧。

class Solution {// Solution2:分治法// 每次找最小的元素为中点,然后向左右两侧递归public int largestRectangleArea(int[] heights) {return helper(heights, 0, heights.length);}public int helper(int[] heights, int l, int r) {if (l == r) return 0;if (l+1 == r) return heights[l];int minIndex = l;for (int i = l+1; i < r; i++) {minIndex = heights[i] < heights[minIndex] ? i : minIndex;}int max = (r - l) * heights[minIndex];int left = helper(heights, l, minIndex);int right = helper(heights, minIndex+1, r);max = Math.max(max, left);return Math.max(max, right);}
}

在这里插入图片描述

5. 剑指 Offer II 040. 矩阵中的最大矩形 – P106

5.1 矩阵转直方图 + 单调栈 – O(mn)(⭐)

时间复杂度 O ( m n ) O(mn) O(mn),空间复杂度 O ( n ) O(n) O(n)

Key:要有抽象思维,将矩阵(01矩阵)抽象成直方图,求1所能构成矩形的最大面积,进而套用上一题的代码,求解直方图的最大面积。

class Solution {// Solution1:将矩阵转化成直方图,求直方图的最大面积public int maximalRectangle(String[] matrix) {if (matrix.length == 0) return 0;char[][] str = new char[matrix.length][];for (int i = 0; i < matrix.length; i++) {str[i] = matrix[i].toCharArray();}int[] heights = new int[str[0].length];int res = 0;for (char[] row : str) {for (int i = 0; i < row.length; i++) {if (row[i] == '0') {heights[i] = 0;} else {heights[i]++;}   }res = Math.max(res, caculateArea(heights));}return res;}public int caculateArea(int[] heights) {Stack<Integer> sk = new Stack<>();sk.push(-1);int max = 0;for (int i = 0; i < heights.length; i++) {while (sk.peek() != -1 && heights[sk.peek()] >= heights[i]) {int h = heights[sk.pop()];int w = i - sk.peek() - 1;max = Math.max(max, h * w);}sk.push(i);}while (sk.peek() != -1) {int h = heights[sk.pop()];int w = heights.length - sk.peek() - 1;max = Math.max(max, h * w);}return max;}
}

在这里插入图片描述

6. 继续提升:加练题目

🎈 可参考:

  • 栈 · SharingSource/LogicStack-LeetCode Wiki · GitHub
  • 单调栈 · SharingSource/LogicStack-LeetCode Wiki · GitHub

相关文章:

【LeetCode】剑指 Offer Ⅱ 第6章:栈(6道题) -- Java Version

题库链接&#xff1a;https://leetcode.cn/problem-list/e8X3pBZi/ 类型题目解决方案栈的应用剑指 Offer II 036. 后缀表达式模拟 栈 ⭐剑指 Offer II 037. 小行星碰撞分类讨论 栈 ⭐单调栈剑指 Offer II 038. 每日温度单调栈 ⭐剑指 Offer II 039. 直方图最大矩形面积单调栈…...

vue3的element-plus的el-dialog的样式修改无效问题

问题描述 想要修改element-plus的对话框el-dialog中的样式&#xff0c;发现在页面style的scoped属性下&#xff0c;使用:deep深入选择器进行修改是无效的。&#xff08;vue2下深度选择器是有效的&#xff09; //无效 :deep(.el-dialog){background-color: transparent; }解决…...

归纳所猜半结论推出完整结论:CF1592F1

https://www.luogu.com.cn/problem/CF1592F1 场上猜了个结论&#xff0c;感觉只会操作1。然后被样例1hack了。然后就猜如果 ( n , m ) (n,m) (n,m) 为1则翻转4操作&#xff0c;被#14hack了。然后就猜4操作只会进行一次&#xff0c;然后就不知道怎么做下去了。 上面猜的结论都…...

WPFdatagrid结合comboBox

在WPF的DataGrid中希望结合使用ComboBox下拉框&#xff0c;达到下拉选择绑定的效果&#xff0c;在实现的过程中&#xff0c;遇到了一些奇怪的问题&#xff0c;因此记录下来。 网上能够查询到的解决方案&#xff1a; 总共有三种ItemSource常见绑定实现方式&#xff1a; 1.ItemS…...

Markdown类图之继承、实现、关联、依赖、组合、聚合总结(十五)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…...

@MultipartConfig注解

前言&#xff1a; 在学习Javaweb的Servlet文件上传和下载的过程中&#xff0c;我们会遇到一个特殊的注解---MultipartConfig。 MultipartConfig的适用情况&#xff1a; 1.文件上传: 当您的应用程序需要接收用户上传的文件时&#xff0c;可以在相应的 Servlet 上使用 Multipart…...

Python并发编程简介

1、Python对并发编程的支持 多线程: threading, 利用CPU和IO可以同时执行的原理,让CPU不会干巴巴等待IO完成多进程: multiprocessing, 利用多核CPU的能力&#xff0c;真正的并行执行任务异步IO: asyncio,在单线程利用CPU和IO同时执行的原理&#xff0c;实现函数异步执行使用Lo…...

WebSocket介绍及部署

WebSocket是一种在单个TCP连接上进行全双工通信的协议&#xff0c;其设计的目的是在Web浏览器和Web服务器之间进行实时通信&#xff08;实时Web&#xff09;。 WebSocket协议的优点包括&#xff1a; 1. 更高效的网络利用率&#xff1a;与HTTP相比&#xff0c;WebSocket的握手…...

自动求导,计算图示意图及pytorch实现

pytorch实现 x1 torch.tensor(3.0, requires_gradTrue) y1 torch.tensor(2.0, requires_gradTrue) a x1 ** 2 b 3 * a c b * y1 c.backward() print(x1.grad) print(y1.grad) print(x1.grad 6 * x1 * y1) print(y1.grad 3 * (x1 ** 2))输出为&#xff1a; tensor(36.) …...

睿伴科创上线了

Robotutor睿伴&#xff0c;一个专业的青少儿编程科创教育品牌和科创服务平台。 Robotutor睿伴拥有一个超过5年的青少儿编程科创教育团队&#xff0c;积累了丰富的课程研发&#xff0c;教学服务和赛事辅导经验。并和上海多所知名高校、上海市计算机学会、上海青少年科学社等开展…...

域名抢注和域名注册

随着互联网的发展&#xff0c;域名已经成为了企业和个人在网络上展示自己的重要标志。如何获得一段好记、易拼写、有意义的域名&#xff0c;是很多人都面临的问题。本文将介绍域名抢注和域名注册的相关内容&#xff0c;并推荐ym.qqmu.com这个可靠的域名注册平台。 一、什么是域…...

【20】c++设计模式——>组合模式

组合模式定义 C组合模式&#xff08;Composite Pattern&#xff09;是一种结构型设计模式&#xff0c;他允许将对象组合成树形结构来表示“部分-整体”的层次结构&#xff1b;在组合模式中有两种基本类型的对象&#xff1a;叶子对象和组合对象&#xff0c;叶子对象时没有子对象…...

Jetpack:004-如何使用文本组件

文章目录 1. 概念介绍2. 使用方法2.1 通用参数2.2 专用参数 3. 示例代码4. 内容总结 我们在上一章回中介绍了Jetpack组件在布局中的对齐方式&#xff0c;本章回中主要介绍文 本组件的使用方法。闲话休提&#xff0c;让我们一起Talk Android Jetpack吧 1. 概念介绍 我们在本章…...

JVM(八股文)

目录 一、JVM简介 二、JVM中的内存区域划分 三、JVM加载 1.类加载 1.1 加载 1.2 验证 1.3 准备 1.4 解析 1.5 初始 1.6 总结 2.双亲委派模型 四、JVM 垃圾回收&#xff08;GC&#xff09; 1.确认垃圾 1.1 引用计数 1.2 可达性分析&#xff08;Java 采用的方案&a…...

C#WPF标记扩展应用实例

本文介绍C#WPF标记扩展应用实例 一、标记扩展 标记扩展是一个 XAML 语言概念。 用于提供特性语法的值时,大括号({ 和 })表示标记扩展用法。 此用法指示 XAML 处理不要像通常那样将特性值视为文本字符串或者可转换为字符串的值。就是类似于值用变量的意思。 WPF 应用编程中…...

四维曲面如何画?matlab

clc; clear all [theta,phi]meshgrid(linspace(0,pi,50),linspace(0,2*pi,50)); zcos(theta); xsin(theta).*cos(phi); ysin(theta).*sin(phi); f-1*((x.*y).2(y.*z).2(z.*x).^2); surf(sin(theta).*cos(phi).*f,sin(theta).*sin(phi).*f,cos(theta).*f,f) 结果...

软件培训测试高级工程师多测师肖sir__html之作业11

html之作业 案例1&#xff1a; 截图&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>表单</title></head><body><table style"background-color:red" bo…...

详解一典型的反激式开关电源方案

理解一个单端反激式开关电源方案&#xff1a; 1、抛出问题&#xff1a; 如图&#xff0c;在某系统方案上看到下图所示的单端反激式开关电源方案。 2、解析问题&#xff1a; 2.1、乍一看&#xff1a; 典型的AC-DC电路&#xff0c;考虑了安规及过压过流保护&#xff0c;如&am…...

AI 大框架基于python来实现基带处理之TensorFlow(信道估计和预测模型,信号解调和解码模型)

AI 大框架基于python来实现基带处理之TensorFlow(信道估计和预测模型,信号解调和解码模型) 基带处理&#xff08;Baseband Processing&#xff09;是一种信号处理技术&#xff0c;用于在通信系统中处理和调制基带信号。基带信号是指未经过调制的信号&#xff0c;通常包含原始数…...

阿里云上了新闻联播

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 阿里新任的CEO吴泳铭上央视新闻联播了! 在昨天的新闻联播里&#xff0c;出席科技座谈会&#xff0c;有一个特别镜头&#xff0c;出现了阿里新任CEO吴泳铭的镜头。 这个信号意义明显&#xff0c;我…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器

一、原理介绍 传统滑模观测器采用如下结构&#xff1a; 传统SMO中LPF会带来相位延迟和幅值衰减&#xff0c;并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF)&#xff0c;可以去除高次谐波&#xff0c;并且不用相位补偿就可以获得一个误差较小的转子位…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...

SQL Server 触发器调用存储过程实现发送 HTTP 请求

文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...

JDK 17 序列化是怎么回事

如何序列化&#xff1f;其实很简单&#xff0c;就是根据每个类型&#xff0c;用工厂类调用。逐个完成。 没什么漂亮的代码&#xff0c;只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...

ArcPy扩展模块的使用(3)

管理工程项目 arcpy.mp模块允许用户管理布局、地图、报表、文件夹连接、视图等工程项目。例如&#xff0c;可以更新、修复或替换图层数据源&#xff0c;修改图层的符号系统&#xff0c;甚至自动在线执行共享要托管在组织中的工程项。 以下代码展示了如何更新图层的数据源&…...

深入解析光敏传感技术:嵌入式仿真平台如何重塑电子工程教学

一、光敏传感技术的物理本质与系统级实现挑战 光敏电阻作为经典的光电传感器件&#xff0c;其工作原理根植于半导体材料的光电导效应。当入射光子能量超过材料带隙宽度时&#xff0c;价带电子受激发跃迁至导带&#xff0c;形成电子-空穴对&#xff0c;导致材料电导率显著提升。…...