【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
题库链接: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中的样式,发现在页面style的scoped属性下,使用:deep深入选择器进行修改是无效的。(vue2下深度选择器是有效的) //无效 :deep(.el-dialog){background-color: transparent; }解决…...
归纳所猜半结论推出完整结论:CF1592F1
https://www.luogu.com.cn/problem/CF1592F1 场上猜了个结论,感觉只会操作1。然后被样例1hack了。然后就猜如果 ( n , m ) (n,m) (n,m) 为1则翻转4操作,被#14hack了。然后就猜4操作只会进行一次,然后就不知道怎么做下去了。 上面猜的结论都…...
WPFdatagrid结合comboBox
在WPF的DataGrid中希望结合使用ComboBox下拉框,达到下拉选择绑定的效果,在实现的过程中,遇到了一些奇怪的问题,因此记录下来。 网上能够查询到的解决方案: 总共有三种ItemSource常见绑定实现方式: 1.ItemS…...
Markdown类图之继承、实现、关联、依赖、组合、聚合总结(十五)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…...
@MultipartConfig注解
前言: 在学习Javaweb的Servlet文件上传和下载的过程中,我们会遇到一个特殊的注解---MultipartConfig。 MultipartConfig的适用情况: 1.文件上传: 当您的应用程序需要接收用户上传的文件时,可以在相应的 Servlet 上使用 Multipart…...
Python并发编程简介
1、Python对并发编程的支持 多线程: threading, 利用CPU和IO可以同时执行的原理,让CPU不会干巴巴等待IO完成多进程: multiprocessing, 利用多核CPU的能力,真正的并行执行任务异步IO: asyncio,在单线程利用CPU和IO同时执行的原理,实现函数异步执行使用Lo…...
WebSocket介绍及部署
WebSocket是一种在单个TCP连接上进行全双工通信的协议,其设计的目的是在Web浏览器和Web服务器之间进行实时通信(实时Web)。 WebSocket协议的优点包括: 1. 更高效的网络利用率:与HTTP相比,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))输出为: tensor(36.) …...
睿伴科创上线了
Robotutor睿伴,一个专业的青少儿编程科创教育品牌和科创服务平台。 Robotutor睿伴拥有一个超过5年的青少儿编程科创教育团队,积累了丰富的课程研发,教学服务和赛事辅导经验。并和上海多所知名高校、上海市计算机学会、上海青少年科学社等开展…...
域名抢注和域名注册
随着互联网的发展,域名已经成为了企业和个人在网络上展示自己的重要标志。如何获得一段好记、易拼写、有意义的域名,是很多人都面临的问题。本文将介绍域名抢注和域名注册的相关内容,并推荐ym.qqmu.com这个可靠的域名注册平台。 一、什么是域…...
【20】c++设计模式——>组合模式
组合模式定义 C组合模式(Composite Pattern)是一种结构型设计模式,他允许将对象组合成树形结构来表示“部分-整体”的层次结构;在组合模式中有两种基本类型的对象:叶子对象和组合对象,叶子对象时没有子对象…...
Jetpack:004-如何使用文本组件
文章目录 1. 概念介绍2. 使用方法2.1 通用参数2.2 专用参数 3. 示例代码4. 内容总结 我们在上一章回中介绍了Jetpack组件在布局中的对齐方式,本章回中主要介绍文 本组件的使用方法。闲话休提,让我们一起Talk Android Jetpack吧 1. 概念介绍 我们在本章…...
JVM(八股文)
目录 一、JVM简介 二、JVM中的内存区域划分 三、JVM加载 1.类加载 1.1 加载 1.2 验证 1.3 准备 1.4 解析 1.5 初始 1.6 总结 2.双亲委派模型 四、JVM 垃圾回收(GC) 1.确认垃圾 1.1 引用计数 1.2 可达性分析(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: 截图: 代码: <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>表单</title></head><body><table style"background-color:red" bo…...
详解一典型的反激式开关电源方案
理解一个单端反激式开关电源方案: 1、抛出问题: 如图,在某系统方案上看到下图所示的单端反激式开关电源方案。 2、解析问题: 2.1、乍一看: 典型的AC-DC电路,考虑了安规及过压过流保护,如&am…...
AI 大框架基于python来实现基带处理之TensorFlow(信道估计和预测模型,信号解调和解码模型)
AI 大框架基于python来实现基带处理之TensorFlow(信道估计和预测模型,信号解调和解码模型) 基带处理(Baseband Processing)是一种信号处理技术,用于在通信系统中处理和调制基带信号。基带信号是指未经过调制的信号,通常包含原始数…...
阿里云上了新闻联播
我是卢松松,点点上面的头像,欢迎关注我哦! 阿里新任的CEO吴泳铭上央视新闻联播了! 在昨天的新闻联播里,出席科技座谈会,有一个特别镜头,出现了阿里新任CEO吴泳铭的镜头。 这个信号意义明显,我…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
