常见“栈“相关题目

找往期文章包括但不限于本期文章中不懂的知识点:

个人主页:我要学编程(ಥ_ಥ)-CSDN博客

所属专栏: 优选算法专题

目录

1047.删除字符串中的所有相邻重复项

844.比较含退格的字符串

227.基本计算器 II

394.字符串解码

946.验证栈序列


1047.删除字符串中的所有相邻重复项

题目:

给出由小写字母组成的字符串 s重复项删除操作会选择两个相邻且相同的字母,并删除它们。

在 s 上反复执行重复项删除操作,直到无法继续删除。

在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

示例:

输入:"abbaca"
输出:"ca"
解释:
例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。

提示:

  1. 1 <= s.length <= 105
  2. s 仅由小写英文字母组成。

思路:这个题目有点类似消消乐这个游戏,这种我们一般都是采用栈的方式来实现。

直接使用栈的方式:遍历字符串,如果栈不为空,且栈顶的元素与当前字符串的元素的值相同,就出栈,否则就进栈。直至遍历完字符串,然后再遍历栈拿到最终的字符序列,最后只需逆置即可。

上面的方式虽然非常简单,但是需要遍历栈拿到字符序列,最后还得去逆置,比较麻烦,我们可以尝试去模拟栈的思想来解决。创建一个StringBuilder对象,当该对象的字符数不为null,且最后一个字符与当前字符串中的元素的值相等时,就删除最后一个字符,否则就加入该对象。最后遍历完成之后,就可以直接返回了。

代码实现:

直接使用栈:

class Solution {// 直接使用栈public String removeDuplicates(String s) {Stack<Character> stack = new Stack<>();for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);// 栈不为空且栈顶元素与当前字符串的元素的值相等,就出栈if (!stack.isEmpty() && stack.peek() == c) {stack.pop();} else {stack.push(c);}}StringBuilder builder = new StringBuilder();while (!stack.isEmpty()) {builder.append(stack.pop());}return builder.reverse().toString();}
}

模拟栈:

class Solution {// 模拟栈的方式public String removeDuplicates(String s) {StringBuilder builder = new StringBuilder();for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);// 与上述栈的处理方式相同if (builder.length() != 0 && builder.charAt(builder.length()-1) == c) {builder.deleteCharAt(builder.length()-1);} else {builder.append(c);}}return builder.toString();}
}

注意:StringBuilder (StringBuffer) 的 capacity方法 与 length方法 的含义不一样。capacity方法是获取其底层的字符数组的大小(不是有效的元素个数,而是总大小),length方法是获取其字符数组的有效长度。 

844.比较含退格的字符串

题目:

给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true 。# 代表退格字符。

注意:如果对空文本输入退格字符,文本继续为空。

示例 1:

输入:s = "ab#c", t = "ad#c"
输出:true
解释:s 和 t 都会变成 "ac"。

示例 2:

输入:s = "ab##", t = "c#d#"
输出:true
解释:s 和 t 都会变成 ""。

示例 3:

输入:s = "a#c", t = "b"
输出:false
解释:s 会变成 "c",但 t 仍然是 "b"。

提示:

  • 1 <= s.length, t.length <= 200
  • s 和 t 只含有小写字母以及字符 '#'

思路:本题也是一个简单的模拟题。遍历字符串,遇到 '#',就删除前面的字符即可,最终只需要判断两个字符串经过上述处理之后的结果是否是一致的。

代码实现:

class Solution {public boolean backspaceCompare(String s, String t) {StringBuilder ss = new StringBuilder();StringBuilder tt = new StringBuilder();for (int i = 0, j = 0; i < s.length() || j < t.length(); i++, j++) {if (i < s.length()) {// 遇到 '#' 且 StringBuilder 对象不为空,就出栈if (s.charAt(i) == '#') {if (ss.length() != 0) {ss.deleteCharAt(ss.length()-1);}} else {ss.append(s.charAt(i));}}if (j < t.length()) {// 遇到 '#' 且 StringBuilder 对象不为空,就出栈if (t.charAt(j) == '#') {if (tt.length() != 0) {tt.deleteCharAt(tt.length()-1);}} else {tt.append(t.charAt(j));}}}return ss.toString().equals(tt.toString());}
}

注意:StringBuilder(StringBuffer) 的 equals 方法并未重写,而是直接继承的Object类的equals方法,比较的是对象的内存地址;而String的equals方法是重写之后的,比较的对象的值。因此这里在比较时,需要先使用 toString方法转换为字符串,再去比较。

227.基本计算器 II

题目:

给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。

整数除法仅保留整数部分。

你可以假设给定的表达式总是有效的。所有中间结果将在 [-231, 231 - 1] 的范围内。

注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval() 。

示例 1:

输入:s = "3+2*2"
输出:7

示例 2:

输入:s = " 3/2 "
输出:1

示例 3:

输入:s = " 3+5 / 2 "
输出:5

提示:

  • 1 <= s.length <= 3 * 10^5
  • s 由整数和算符 ('+', '-', '*', '/') 组成,中间由一些空格隔开
  • s 表示一个 有效表达式
  • 表达式中的所有整数都是非负整数,且在范围 [0, 2^31 - 1] 内
  • 题目数据保证答案是一个 32-bit 整数

思路:题目就是让我们计算出一段字符串序列的最终值,而这个字符串序列中包含了 +、-、*、/、空格 与 数字。由于在计算字符串序列的值时,乘除运算符的优先级是高于加减的,因此我们可以先将乘除的运算全部先计算出来,最后再去计算出加减的值。那我们就可以先遍历字符串,如果遇到了空格可以直接跳过,如果遇到了数字字符,就拿到完整的数字(可能不是一位数),然后根据前者的运算符是啥,来决定当前数据做什么处理,如果遇到了运算符,就直接记录下来即可。

代码实现:

class Solution {public int calculate(String s) {int n = s.length(), i = 0;char[] strs = s.toCharArray();Stack<Integer> stack = new Stack<>();char op = '+'; // 初始化为'+'while (i < n) {// 排除空格的情况while (i < n && strs[i] == ' ') { // 避免越界i++;}if (i == n) {break;}// 处理数字if (i < n && strs[i] >= '0' && strs[i] <= '9') {// 先拿到完整的数字int num = 0;while (i < n && strs[i] >= '0' && strs[i] <= '9') {num = num * 10 + (strs[i] - '0');i++;}// 根据运算符的情况,将不同情况的数据入栈if (op == '+') { // 加上数据stack.push(num);} else if (op == '-') { // 减去数据stack.push(-num);} else if (op == '*') { // 让栈顶的数据乘上该数据stack.push(stack.pop() * num);} else { // 让栈顶的数据除去该数据stack.push(stack.pop() / num);}// 处理完上述不需要 i++,因为上述刚好将i+1的位置确认为非数字,但未处理} else {// 处理运算符op = strs[i];i++;}}// 将栈中所有元素相加即可int ret = 0;while (!stack.isEmpty()) {ret += stack.pop();}return ret;}
}

394.字符串解码

题目:

给定一个经过编码的字符串,返回它解码后的字符串。

编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。

你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。

此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。

示例 1:

输入:s = "3[a]2[bc]"
输出:"aaabcbc"

示例 2:

输入:s = "3[a2[c]]"
输出:"accaccacc"

示例 3:

输入:s = "2[abc]3[cd]ef"
输出:"abcabccdcdcdef"

示例 4:

输入:s = "abc3[cd]xyz"
输出:"abccdcdcdxyz"

提示:

  • 1 <= s.length <= 30
  • s 由小写英文字母、数字和方括号 '[]' 组成
  • s 保证是一个 有效 的输入。
  • s 中所有整数的取值范围为 [1, 300] 

思路:本题和表达式求值的思路是类似的,都是先计算出优先级较高的。而这里是需要我们先将括号内的字符串解析出来,然后再去拼接出最终的字符串。内嵌的字符串的优先级是最高的,也是最先需要解析出来的。

代码实现:

class Solution {public String decodeString(String s) {// 创建一个数字栈、一个字符串栈Stack<String> s_stack = new Stack<>();Stack<Integer> n_stack = new Stack<>();s_stack.push(""); // 避免纯字符前缀无法添加到栈顶元素的末尾int n = s.length(), i = 0;char[] strs = s.toCharArray();while (i < n) {if (strs[i] >= '0' && strs[i] <= '9') { // 数字int num = 0;while (strs[i] >= '0' && strs[i] <= '9') { // 可能不止一位数num = num * 10 + (strs[i] - '0');i++;}n_stack.push(num); // 数字入栈} else if (strs[i] == '[') { // 左括号// 字符串入栈i++;StringBuilder builder = new StringBuilder();// 只需要加入字母,避免右括号 与 数字while (strs[i] != ']' && strs[i] <= '0' && strs[i] >= '9') {builder.append(strs[i++]);}s_stack.push(builder.toString());} else if (strs[i] == ']') { // 右括号// 字符串栈 出栈,数字栈 出栈StringBuilder builder = new StringBuilder(s_stack.pop());StringBuilder tmp = new StringBuilder(builder);int k = n_stack.pop();for (int j = 0; j < k-1; j++) {tmp.append(builder);}// 添加到栈顶元素的末尾builder = new StringBuilder(s_stack.pop());s_stack.push(builder.append(tmp).toString());i++;} else { // 纯字符串// 拿到字符串StringBuilder tmp = new StringBuilder();while (i < n && strs[i] >= 'a' && strs[i] <= 'z') {tmp.append(strs[i++]);}// 直接添加到栈顶元素的末尾StringBuilder builder = new StringBuilder(s_stack.pop());builder.append(tmp);s_stack.push(builder.toString());}}return s_stack.pop().toString();}
}

946.验证栈序列

题目:

给定 pushed 和 popped 两个序列,每个序列中的 值都不重复,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时,返回 true;否则,返回 false 。

示例 1:

输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
输出:true
解释:我们可以按以下顺序执行:
push(1), push(2), push(3), push(4), pop() -> 4,
push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1

示例 2:

输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
输出:false
解释:1 不能在 2 之前弹出。

提示:

  • 1 <= pushed.length <= 1000
  • 0 <= pushed[i] <= 1000
  • pushed 的所有元素 互不相同
  • popped.length == pushed.length
  • popped 是 pushed 的一个排列

思路:只需要将push序列一直进栈,并同时判断栈顶的元素是否与指向popped序列的指针值是否一致,如果一致的话,就一致出栈,直至栈为空,如果不一致就一直进栈。重复上述过程,直至最终的栈为空,或者指向popped序列的值为空,说明出栈序列是正确的,反之,则是错误的。

代码实现:

class Solution {public boolean validateStackSequences(int[] pushed, int[] popped) {Stack<Integer> stack = new Stack<>();int i = 0, j = 0, n = popped.length;while (i < n) {stack.push(pushed[i]);while (!stack.isEmpty() && stack.peek() == popped[j]) {stack.pop();j++;}i++;}return stack.isEmpty();}
}

好啦!本期 常见“栈“相关题目 的刷题之旅 就到此结束啦!我们下一期再一起学习吧!

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

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

相关文章

窥探目标文件

文章目录 源文件如何变成可执行文件编译链接目标文件格式ELF文件格式节表重定位表(.rela)符号表(.symtab)符号(链接的接口)强符号与弱符号强引用与弱引用符号表表项符号类型和绑定信息符号所在段其他节源文件如何变成可执行文件 CPU只能执行二进制指令,无法执行用户直接编写的…

22.Word:小张-经费联审核结算单❗【16】

目录 NO1.2 NO3.4​ NO5.6.7 NO8邮件合并 MS搜狗输入法 NO1.2 用ms打开文件&#xff0c;而不是wps❗不然后面都没分布局→页面设置→页面大小→页面方向→上下左右&#xff1a;页边距→页码范围&#xff1a;多页&#xff1a;拼页光标处于→布局→分隔符&#xff1a;分节符…

java求职学习day23

MySQL 单表 & 约束 & 事务 1. DQL操作单表 1.1 创建数据库,复制表 1) 创建一个新的数据库 db2 CREATE DATABASE db2 CHARACTER SET utf8; 2) 将 db1 数据库中的 emp 表 复制到当前 db2 数据库 1.2 排序 通过 ORDER BY 子句 , 可以将查询出的结果进行排序 ( 排序只…

你了解哪些Java限流算法?

大家好&#xff0c;我是锋哥。今天分享关于【你了解哪些Java限流算法?】面试题。希望对大家有帮助&#xff1b; 你了解哪些Java限流算法? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Java 中常用的限流算法主要有以下几种&#xff0c;它们广泛应用于处理流量控…

【HarmonyOS之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(二)

目录 1 -> HML语法 1.1 -> 页面结构 1.2 -> 数据绑定 1.3 -> 普通事件绑定 1.4 -> 冒泡事件绑定5 1.5 -> 捕获事件绑定5 1.6 -> 列表渲染 1.7 -> 条件渲染 1.8 -> 逻辑控制块 1.9 -> 模板引用 2 -> CSS语法 2.1 -> 尺寸单位 …

51单片机CLD1602显示万年历+闹钟+农历+整点报时

1. 硬件设计 硬件是我自己设计的一个通用的51单片机开发平台&#xff0c;可以根据需要自行焊接模块&#xff0c;这是用立创EDA画的一个双层PCB板&#xff0c;所以模块都是插针式&#xff0c;不是表贴的。电路原理图在文末的链接里&#xff0c;PCB图暂时不选择开源。 B站上传的…

CSS核心

CSS的引入方式 内部样式表是在 html 页面内部写一个 style 标签&#xff0c;在标签内部编写 CSS 代码控制整个 HTML 页面的样式。<style> 标签理论上可以放在 HTML 文档的任何地方&#xff0c;但一般会放在文档的 <head> 标签中。 <style> div { color: r…

具身智能体空间感知基础!ROBOSPATIAL:评测并增强2D和3D视觉语言模型空间理解水平

作者&#xff1a;Chan Hee Song, Valts Blukis,Jonathan Tremblay, Stephen Tyree, Yu Su, Stan Birchfield 单位&#xff1a;俄亥俄州立大学&#xff0c;NVIDIA 论文标题&#xff1a;ROBOSPATIAL: Teaching Spatial Understanding to 2D and 3D Vision-Language Models for …

【C语言】动态内存管理

1、为什么存在动态内存分配&#xff1f;2、动态内存管理函数介绍&#xff08;1&#xff09;malloc&#xff08;2&#xff09;free&#xff08;3&#xff09;calloc&#xff08;4&#xff09;realloc 3、常见动态内存错误&#xff08;1&#xff09;使用free释放动态内存开辟的一…

实验八 JSP访问数据库

实验八 JSP访问数据库 目的&#xff1a; 1、熟悉JDBC的数据库访问模式。 2、掌握使用My SQL数据库的使用 实验要求&#xff1a; 1、通过JDBC访问mysql数据&#xff0c;实现增删改查功能的实现 2、要求提交实验报告&#xff0c;将代码和实验结果页面截图放入报告中 实验过程&a…

RabbitMQ5-死信队列

目录 死信的概念 死信的来源 死信实战 死信之TTl 死信之最大长度 死信之消息被拒 死信的概念 死信&#xff0c;顾名思义就是无法被消费的消息&#xff0c;一般来说&#xff0c;producer 将消息投递到 broker 或直接到queue 里了&#xff0c;consumer 从 queue 取出消息进…

【项目初始化】

项目初始化 使用脚手架创建项目Vite创建项目推荐拓展 使用脚手架创建项目 Vite Vite 是一个现代的前端构建工具&#xff0c;它提供了极速的更新和开发体验&#xff0c;支持多种前端框架&#xff0c;如 Vue、React 等创建项目 pnpm create vuelatest推荐拓展

一文读懂 Faiss:开启高维向量高效检索的大门

一、引言 在大数据与人工智能蓬勃发展的当下&#xff0c;高维向量数据如潮水般涌现。无论是图像、音频、文本&#xff0c;还是生物信息领域&#xff0c;都离不开高维向量来精准刻画数据特征。然而&#xff0c;在海量的高维向量数据中进行快速、准确的相似性搜索&#xff0c;却…

基于Django的Boss直聘IT岗位可视化分析系统的设计与实现

【Django】基于Django的Boss直聘IT岗位可视化分析系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 该系统采用Python作为主要开发语言&#xff0c;利用Django这一高效、安全的W…

python 语音识别

目录 一、语音识别 二、代码实践 2.1 使用vosk三方库 2.2 使用SpeechRecognition 2.3 使用Whisper 一、语音识别 今天识别了别人做的这个app,觉得虽然是个日记app 但是用来学英语也挺好的,能进行语音识别,然后矫正语法,自己说的时候 ,实在不知道怎么说可以先乱说,然…

栈和队列特别篇:栈和队列的经典算法问题

图均为手绘,代码基于vs2022实现 系列文章目录 数据结构初探: 顺序表 数据结构初探:链表之单链表篇 数据结构初探:链表之双向链表篇 链表特别篇:链表经典算法问题 数据结构:栈篇 数据结构:队列篇 文章目录 系列文章目录前言一.有效的括号(leetcode 20)二.用队列实现栈(leetcode…

使用 OpenResty 构建高效的动态图片水印代理服务20250127

使用 OpenResty 构建高效的动态图片水印代理服务 在当今数字化的时代&#xff0c;图片在各种业务场景中广泛应用。为了保护版权、统一品牌形象&#xff0c;动态图片水印功能显得尤为重要。然而&#xff0c;直接在后端服务中集成水印功能&#xff0c;往往会带来代码复杂度增加、…

C++并行化编程

C并行化编程 C 简介 C 是一种静态类型的、编译式的、通用的、大小写敏感的、不规则的编程语言&#xff0c;支持过程化编程、面向对象编程和泛型编程。 C 被认为是一种中级语言&#xff0c;它综合了高级语言和低级语言的特点。 C 是由 Bjarne Stroustrup 于 1979 年在新泽西州美…

Java开发vscode环境搭建

1 几个名词 JDK Java Development Kit JRE Java Runtion Environment JVM JDK 包括 Compiler,debugger,JRE等。JRE包括JVM和Runtime Library。 2 配置环境 2.1 安装JDK 类比 C/C的 g工具 官网&#xff1a;https://www.oracle.com/java/technologies/downloads/ 根据自己使…

pytorch基于FastText实现词嵌入

FastText 是 Facebook AI Research 提出的 改进版 Word2Vec&#xff0c;可以&#xff1a; ✅ 利用 n-grams 处理未登录词 比 Word2Vec 更快、更准确 适用于中文等形态丰富的语言 完整的 PyTorch FastText 代码&#xff08;基于中文语料&#xff09;&#xff0c;包含&#xff1…