代码随想录_栈与队列
栈与队列
232.用栈实现队列
232. 用栈实现队列
使用栈实现队列的下列操作:
push(x) – 将一个元素放入队列的尾部。
pop() – 从队列首部移除元素。
peek() – 返回队列首部的元素。
empty() – 返回队列是否为空。
思路: 定义两个栈: 入队栈, 出队栈, 控制出入栈顺序, 进入的元素倒两次就是原顺序
代码:
class MyQueue {Stack<Integer> in;Stack<Integer> out;public MyQueue() {in = new Stack<>();out = new Stack<>();}public void push(int x) {in.push(x);}public int pop() {inToOut();return out.pop();}public int peek() {inToOut();return out.peek();}private void inToOut() {// out非空时不能往里面倒, 出的时候要先把out里的出完, 再倒入// 否则原来的数据会被覆盖if(!out.isEmpty()) return;while(!in.isEmpty()) {out.push(in.pop());}}public boolean empty() {return in.isEmpty() && out.isEmpty();}
}
225. 用队列实现栈
225. 用队列实现栈
使用队列实现栈的下列操作:
- push(x) – 元素 x 入栈
- pop() – 移除栈顶元素
- top() – 获取栈顶元素
- empty() – 返回栈是否为空
思路: 每次pop, peek都要reposition
代码:
class MyStack {Queue<Integer> queue;public MyStack() {queue = new LinkedList<>();}public void push(int x) {queue.offer(x);}public int pop() {reposition();// 每次pop时将队列前size - 1个放到队列末尾return queue.poll();}public int top() {reposition();// 每次pop时将队列前size - 1个放到队列末尾int n = queue.poll();queue.offer(n);return n;}public boolean empty() {return queue.isEmpty();}private void reposition() {int size = queue.size();size--;while(size-- > 0) {queue.offer(queue.poll());}}
}
20. 有效的括号
20. 有效的括号
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 注意空字符串可被认为是有效字符串。
思路:
一共有三种情况:
-
字符串里左方向的括号多余了 ,所以不匹配。
-
括号没有多余,但是 括号的类型没有匹配上。
-
字符串里右方向的括号多余了,所以不匹配。
每一个左括号, 压入对应的右括号, 当开始遍历右括号时, 按照如下方式和栈中元素进行对比
代码:
class Solution {public boolean isValid(String s) {// 0. 剪枝int len = s.length();if(len % 2 != 0) return false;// 长度为奇数, 则一定不能匹配// 1. 初始化栈Stack<Character> stack = new Stack<>();// 2. 遍历每一个字符for(int i = 0;i < len;i++) {// 2.1 每一个左括号, 压入对应的右括号if(s.charAt(i) == '(') {stack.push(')');}else if(s.charAt(i) == '[') {stack.push(']');}else if(s.charAt(i) == '{') {stack.push('}');// 2.2 每一个右括号, 查看栈中对应的右括号是否相等}else if(stack.isEmpty() || s.charAt(i) != stack.peek()) {// 不能是s.pop,否则在判断时就会将元素弹出return false;}else {// 右括号匹配, 出栈stack.pop();}}// 3. 遍历完后, 查看栈中是否还有右括号(左括号多余)return stack.isEmpty();}
}
1047. 删除字符串中的所有相邻重复项
1047. 删除字符串中的所有相邻重复项
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
示例:
- 输入:“abbaca”
- 输出:“ca”
- 解释:例如,在 “abbaca” 中,我们可以删除 “bb” 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 “aaca”,其中又只有 “aa” 可以执行重复项删除操作,所以最后的字符串为 “ca”。
法一: 栈
思路: 用字符串模拟栈(也可以直接用栈, 需要再转为字符串)进行"消消乐", 留下的就是最终的字符串
代码:
class Solution {public String removeDuplicates(String s) {// 1. 定义字符串模拟栈StringBuilder sb = new StringBuilder();// 2. 遍历s的每一位, 与栈进行消除int top = -1;for(int i = 0;i < s.length();i++) {if(top >= 0 && s.charAt(i) == sb.charAt(top)) {sb.deleteCharAt(top--);}else {sb.append(s.charAt(i));top++;}}// 3. 返回return sb.toString();}
}
法二:双指针
思路: 快指针指向原字符串要处理的字符, 慢指针指向新的字符串, 当新字符串出现相邻相等的情况, 则将两个同时排除, 回退到第一次出现该字符的位置, 继续遍历原字符串的下一个字符, 否则, 快慢指针同时往前走.
代码:
class Solution {public String removeDuplicates(String s) {// 1. 初始化char[] str = s.toCharArray();int fast = 0,slow = 0;// 2. 遍历原字符串while(fast < str.length) {str[slow] = str[fast++];// 2.1 新的字符串出现成对可消除, 走到第一次出现的位置, 覆盖(同时消除)if(slow > 0 && str[slow] == str[slow - 1]) {slow--;}else{// 2.2 没有可消除的字符, fast slow都往后走slow++;}}// 3. 返回return new String(str,0,slow);}
}
150. 逆波兰表达式求值
150. 逆波兰表达式求值
根据 逆波兰表示法,求表达式的值。
有效的运算符包括 + , - , * , / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
说明:
整数除法只保留整数部分。 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
示例 1:
- 输入: [“2”, “1”, “+”, “3”, " * "]
- 输出: 9
- 解释: 该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
思路: 栈, 每遇到一个操作符, 就对栈中的两个数组进行计算, 注意: 栈中的顺序与原来后缀表达式计算顺序相反, 因此弹出来的两个数字运算时交换顺序注意: 栈中的顺序与原来后缀表达式计算顺序相反, 因此弹出来的两个数字运算时交换顺序.
代码:
class Solution {public int evalRPN(String[] tokens) {// 0. 剪枝if(tokens.length == 1) return Integer.valueOf(tokens[0]);// 1. 定义栈Stack<Integer> sk = new Stack<>();// 2. 逐个处理for(String s : tokens) {// 2.1 处理运算符if("+".equals(s) || "-".equals(s) || "*".equals(s) || "/".equals(s)) {// 注意: 栈中的顺序与原来后缀表达式计算顺序相反, 因此弹出来的两个数字运算时交换顺序int n = sk.pop();int m = sk.pop();if("+".equals(s)) {sk.push(m + n);}else if("-".equals(s)) {sk.push(m - n);}else if("*".equals(s)) {sk.push(m * n);}else if("/".equals(s)) {sk.push(m / n);}}else {// 2.2 处理数字sk.push(Integer.valueOf(s));}}// 3. 返回return sk.pop();}
}
239. 滑动窗口最大值
239. 滑动窗口最大值
给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回滑动窗口中的最大值。
进阶:
你能在线性时间复杂度内解决此题吗?

提示:
- 1 <= nums.length <= 10^5
- -10^4 <= nums[i] <= 10^4
- 1 <= k <= nums.length
思路: 单调队列, 保证队头为窗口内最大值, 保证每次队列内有不多于k个元素
代码:
class Solution {public int[] maxSlidingWindow(int[] nums, int k) {// 1. 定义容器ArrayDeque<Integer> q = new ArrayDeque<>();int n = nums.length,index = 0;int[] ans = new int[n - k + 1];// 2. 循环遍历for(int i = 0;i < n;i++) {// 2.1 出: 将不符合窗口范围的移出while(!q.isEmpty() && q.peek() < (i - k + 1)) q.poll();// 2.2 入: 先将比该数值小的从后往前依次移出(保证单调), 再放入while(!q.isEmpty() && nums[q.peekLast()] < nums[i]) q.pollLast();q.offer(i);// 2.3 收集: 当窗口中走够k个元素时, 开始收集if(i >= k - 1) ans[index++] = nums[q.peek()];}// 3. 返回return ans;}
}
347.前 K 个高频元素
347. 前 K 个高频元素
给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
示例 1:
- 输入: nums = [1,1,1,2,2,3], k = 2
- 输出: [1,2]
示例 2:
- 输入: nums = [1], k = 1
- 输出: [1]
思路: map统计num及其出现次数, PriorityQueue用作小顶堆, 维护前k个出现次数最多的entry
代码:
class Solution {public int[] topKFrequent(int[] nums, int k) {// 1. 定义容器int[] ans = new int[k];Map<Integer,Integer> map = new HashMap<>();PriorityQueue<int[]> pq = new PriorityQueue<>((o1,o2) -> o1[1] - o2[1]);// 2. 填充mapfor(int num : nums) {map.put(num,map.getOrDefault(num,0) + 1);}// 3. 填充pqSet<Map.Entry<Integer,Integer>> entries = map.entrySet();for(Map.Entry<Integer,Integer> e : entries) {int[] t = new int[2];t[0] = e.getKey();t[1] = e.getValue();pq.offer(t);// 维持小顶堆中3个出现次数最多元素if(pq.size() > k) pq.poll();}// 4. 返回for(int i = 0;i < k;i++) {ans[i] = pq.poll()[0];}return ans;}
}
相关文章:
代码随想录_栈与队列
栈与队列 232.用栈实现队列 232. 用栈实现队列 使用栈实现队列的下列操作: push(x) – 将一个元素放入队列的尾部。 pop() – 从队列首部移除元素。 peek() – 返回队列首部的元素。 empty() – 返回队列是否为空。 思路: 定义两个栈: 入队栈, 出队栈, 控制出入…...
Ubuntu 手动安装 Open WebUI 完整指南
Ubuntu 手动安装 Open WebUI 完整指南 前提条件 在安装 Open WebUI 之前,请确保您的系统满足以下要求: Ubuntu 22.04 LTS 或更高版本Python 3.10Node.js 18Git至少 4GB 内存足够的磁盘空间(推荐 20GB 以上) 安装步骤 1. 更新…...
【Oracle篇】使用Hint对优化器的执行计划进行干预(含单表、多表、查询块、声明四大类Hint干预)
💫《博主介绍》:✨又是一天没白过,我是奈斯,从事IT领域✨ 💫《擅长领域》:✌️擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控;并对SQLserver、NoSQL(…...
论文阅读(九):通过概率图模型建立连锁不平衡模型和进行关联研究:最新进展访问之旅
1.论文链接:Modeling Linkage Disequilibrium and Performing Association Studies through Probabilistic Graphical Models: a Visiting Tour of Recent Advances 摘要: 本章对概率图模型(PGMs)的最新进展进行了深入的回顾&…...
【信息系统项目管理师-选择真题】2005上半年综合知识答案和详解
更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 【第1题】【第2~3题】【第4~6题】【第7题】【第8题】【第9题】【第10~11题】【第12题】【第13题】【第14题】【第15题】【第16题】【第17题】【第18~19题】【第20题】【第21~22题】【第23题】【第24~25题】【第…...
【Matlab高端绘图SCI绘图模板】第006期 对比绘柱状图 (只需替换数据)
1. 简介 柱状图作为科研论文中常用的实验结果对比图,本文采用了3组实验对比的效果展示图,代码已调试好,只需替换数据即可生成相关柱状图,为科研加分。通过获得Nature配色的柱状图,让你的论文看起来档次更高࿰…...
【Elasticsearch】 Intervals Query
Elasticsearch Intervals Query 返回基于匹配术语的顺序和接近度的文档。 intervals 查询使用 匹配规则,这些规则由一小组定义构建而成。这些规则然后应用于指定 field 中的术语。 这些定义生成覆盖文本中术语的最小间隔序列。这些间隔可以进一步由父源组合和过滤…...
YOLOv8源码修改(4)- 实现YOLOv8模型剪枝(任意YOLO模型的简单剪枝)
目录 前言 1. 需修改的源码文件 1.1添加C2f_v2模块 1.2 修改模型读取方式 1.3 增加 L1 正则约束化训练 1.4 在tensorboard上增加BN层权重和偏置参数分布的可视化 1.5 增加剪枝处理文件 2. 工程目录结构 3. 源码文件修改 3.1 添加C2f_v2模块和模型读取 3.2 添加L1正则…...
数论问题80
命题1,证明,方程(2x)^(2x)-1y^(z1)没有正整数解。 分析:设x,y,z∈Z满足方程,当x1时,3y^(z1),无论任意y,z取任意正整数值,3y^(z1)都不成立。方程左端分解因式,…...
后端token校验流程
获取用户信息 前端中只有 await userStore.getInfo() 表示从后端获取数据 在页面中找到info对应的url地址,在IDEA中查找 这里是getInfo函数的声明,我们要找到这个函数的使用,所以点getInfo() Override public JSONObject getInfo() {JSO…...
Ansible自动化运维实战--通过role远程部署nginx并配置(8/8)
文章目录 1、准备工作2、创建角色结构3、编写任务4、准备配置文件(金甲模板)5、编写变量6、编写处理程序7、编写剧本8、执行剧本Playbook9、验证-游览器访问每台主机的nginx页面 在 Ansible 中,使用角色(Role)来远程部…...
C语言自定义数据类型详解(二)——结构体类型(下)
书接上回,前面我们已经给大家介绍了如何去声明和创建一个结构体,如何初始化结构体变量等这些关于结构体的基础知识。下面我们将继续给大家介绍和结构体有关的知识: 今天的主题是:结构体大小的计算并简单了解一下位段的相关知识。…...
OpenFeign的工作原理是什么?它第一次加载的时候为什么慢?
OpenFeign的工作原理是什么?它第一次加载的时候为什么慢? OpenFeign的工作原理 接口定义: 开发者定义一个接口,并使用 FeignClient 注解指定该接口所对应的微服务名称。在接口的方法上添加 HTTP 方法相关的注解(如 …...
LLM架构与优化:从理论到实践的关键技术
标题:“LLM架构与优化:从理论到实践的关键技术” 文章信息摘要: 文章探讨了大型语言模型(LLM)开发与应用中的关键技术,包括Transformer架构、注意力机制、采样技术、Tokenization等基础理论,以…...
Maven的单元测试
1. 单元测试的基本概念 单元测试(Unit Testing) 是一种软件测试方法,专注于测试程序中的最小可测试单元——通常是单个类或方法。通过单元测试,可以确保每个模块按预期工作,从而提高代码的质量和可靠性。 2.安装和配…...
Jetson Xavier NX 安装 CUDA 支持的 PyTorch 指南
本指南将帮助开发者完成在 Jetson Xavier NX 上安装 CUDA 支持的 PyTorch。 安装方法 在 Jetson 上安装 Pytorch 只有两种方法。 一种是直接安装他人已经编译好的 PyTorch 轮子;一种是自己从头开始开始构建 PyTorch 轮子并且安装。 使用轮子安装 可以从我的 Gi…...
AI协助探索AI新构型的自动化创新概念
训练AI自生成输出模块化代码,生成元代码级别的AI功能单元代码,然后再由AI组织为另一个AI,实现AI开发AI的能力;用AI协助探索迭代新构型AI将会出现,并成为一种新的技术路线潮流。 有限结点,无限的连接形式&a…...
Kafka 压缩算法详细介绍
文章目录 一 、Kafka 压缩算法概述二、Kafka 压缩的作用2.1 降低网络带宽消耗2.2 提高 Kafka 生产者和消费者吞吐量2.3 减少 Kafka 磁盘存储占用2.4 减少 Kafka Broker 负载2.5 降低跨数据中心同步成本 三、Kafka 压缩的原理3.1 Kafka 压缩的基本原理3.2. Kafka 压缩的工作流程…...
GWO优化GRNN回归预测matlab
灰狼优化算法(Grey Wolf Optimizer,简称 GWO),是一种群智能优化算法,由澳大利亚格里菲斯大学的 Mirjalii 等人于 2014 年提出。该算法的设计灵感源自灰狼群体的捕食行为,核心思想在于模拟灰狼社会的结构与行…...
Unity 粒子特效在UI中使用裁剪效果
1.使用Sprite Mask 首先建立一个粒子特效在UI中显示 新建一个在场景下新建一个空物体,添加Sprite Mask组件,将其的Layer设置为UI相机渲染的UI层, 并将其添加到Canvas子物体中,调整好大小,并选择合适的Spriteÿ…...
【大厂AI实践】OPPO:大规模知识图谱及其在小布助手中的应用
导读:OPPO知识图谱是OPPO数智工程系统小布助手团队主导、多团队协作建设的自研大规模通用知识图谱,目前已达到数亿实体和数十亿三元组的规模,主要落地在小布助手知识问答、电商搜索等场景。 本文主要分享OPPO知识图谱建设过程中算法相关的技…...
C# 添加、替换、提取、或删除Excel中的图片
在Excel中插入与数据相关的图片,能将关键数据或信息以更直观的方式呈现出来,使文档更加美观。此外,对于已有图片,你有事可能需要更新图片以确保信息的准确性,或者将Excel 中的图片单独保存,用于资料归档、备…...
AI大模型开发原理篇-5:循环神经网络RNN
神经概率语言模型NPLM也存在一些明显的不足之处:模型结构简单,窗口大小固定,缺乏长距离依赖捕捉,训练效率低,词汇表固定等。为了解决这些问题,研究人员提出了一些更先进的神经网络语言模型,如循环神经网络、…...
赛博算卦之周易六十四卦JAVA实现:六幺算尽天下事,梅花化解天下苦。
佬们过年好呀~新年第一篇博客让我们来场赛博算命吧! 更多文章:个人主页 系列文章:JAVA专栏 欢迎各位大佬来访哦~互三必回!!! 文章目录 #一、文化背景概述1.文化起源2.起卦步骤 #二、卦象解读#三、just do i…...
iperf 测 TCP 和 UDP 网络吞吐量
注:本文为 “iperf 测网络吞吐量” 相关文章合辑。 未整理去重。 使用 iperf3 监测网络吞吐量 Tom 王 2019-12-21 22:23:52 一 iperf3 介绍 (1.1) iperf3 是一个网络带宽测试工具,iperf3 可以擦拭 TCP 和 UDP 带宽质量。iperf3 可以测量最大 TCP 带宽…...
内外网文件摆渡企业常见应用场景和对应方案
在如今的企业环境中,内外网文件摆渡的需求越来越常见,也变得越来越重要。随着信息化的不断推进,企业内部和外部之间的数据交换越来越频繁,如何安全、高效地进行文件传输成了一个关键问题。今天,咱就来聊聊内外网文件摆…...
【微服务与分布式实践】探索 Sentinel
参数设置 熔断时长 、最小请求数、最大RT ms、比例阈值、异常数 熔断策略 慢调⽤⽐例 当单位统计时⻓内请求数⽬⼤于设置的最⼩请求数⽬,并且慢调⽤的⽐例⼤于阈值,则接下来的熔断时⻓内请求会⾃动被熔断 异常⽐例 当单位统计时⻓内请求数⽬⼤于设置…...
论文阅读(十五):DNA甲基化水平分析的潜变量模型
1.论文链接:Latent Variable Models for Analyzing DNA Methylation 摘要: 脱氧核糖核酸(DNA)甲基化与细胞分化密切相关。例如,已经观察到肿瘤细胞中的DNA甲基化编码关于肿瘤的表型信息。因此,通过研究DNA…...
Android View 的事件分发机制解析
前言:当一个事件发生时(例如触摸屏幕),事件会从根View(通常是Activity的布局中的最顶层View)开始,通过一个特定的路径传递到具体的View,这个过程涉及到三个关键的阶段:事…...
内容检索(2025.01.30)
随着创作数量的增加,博客文章所涉及的内容越来越庞杂,为了更为方便地阅读,后续更新发布的文章将陆续在此汇总并附上原文链接,感兴趣的小伙伴们可持续关注文章发布动态! 博客域名:http://my-signal.blog.cs…...
