stack queue Leetcode 栈和队列算法题

232.用栈实现队列

Queue 是 Collection 接口下的,她的一个实现类是ArrayDeque.

不推荐使用 Vector 实现的 Stack,因为为了保证线程安全使得 Stack 的效率很低,而且由于继承的 Vector 导致没有屏蔽一些栈不应该有的操作

  • stack 下使用入栈出栈的Api是 push 和 pop

两个栈实现队列:

  • 一个栈用于放数据
  • 一个栈用于读数据,这时读出的数据是按照队列的顺序的,
  • 所以每次读的时候就先判断读数据的栈是否为空,先从读数据的栈中拿数据,如果为空,则把存数据的栈倒入读数据的栈
  • 每次读完不需要再把数据倒回去,因为是优先从读数据的栈中取数据的,后加入的数据不会和之前的数据混乱,因为之前的数据读完了才能轮到后面的数据
class MyQueue {private Deque<Integer> inStack;private Deque<Integer> outStack;public MyQueue() {inStack = new ArrayDeque<Integer>();outStack = new ArrayDeque<Integer>();}public void push(int x) {inStack.push(x);}private void inToOut(){while(!inStack.isEmpty()){outStack.push(inStack.pop());}}public int pop() {if(outStack.isEmpty()){inToOut();}return outStack.pop();}public int peek() {if(outStack.isEmpty()){inToOut();}return outStack.peek();}public boolean empty() {if(outStack.isEmpty() && inStack.isEmpty()){return true;}return false;}
}

225.用队列实现栈

用两个队列实现栈,第一个队列用于按照栈的顺序存放队列,当来一个新数据 x 如需要入栈的时候,我们要把这个数据 x 放在队列的最前面

队列的实现方式:LinkedList 实现了 Deque 和 List 两个接口

Deque是双端队列,既可以当作栈,也可以当作队列,当作队列使用时:

  • 入队尾用 offer() / add()
  • 出队头用 poll()
  • 与 add() push() pop() 的不同在与
    • offer/poll不会抛出异常
    • push() 是针对栈的操作,如果在队列中使用的话,添加的元素是加载队头的
Deque<Integer> queue = new LinkedList<>();

实现方法一:

  • queue1 把所有的数据先倒入 queue2,然后把 x 放入 queue1 里
  • 然后再把 queue2 里的数据倒回 queue1,这样新加入的数据就在 queue1 队列头部
  • 问题是这样原本的数据在两个队列中倒了两次(移动了两次)
class MyStack {private Deque<Integer> queue1;private Deque<Integer> queue2;public MyStack() {queue1 = new LinkedList<Integer>();queue2 = new LinkedList<Integer>();}public void push(int x) {while(!queue1.isEmpty()){queue2.offer(queue1.poll());}queue1.offer(x);while(!queue2.isEmpty()){queue1.offer(queue2.poll());}}public int pop() {return queue1.poll();}public int top() {return queue1.peek();}public boolean empty() {return queue1.isEmpty();}
}

实现方法二:

  • x 放入 queue2 中,这样新加入的数据就在 queue2 队列头部
  • 然后在把 queue1 中的数据导入 queue2 中,这样 queue2 的数据就是按照栈的顺序存放的
  • 最后交换 queue1 和 queue2 指向的队列,这样 queue1就指向的是那个按照栈顺序存放的队列,而 queue2变成了空队列
  • 这样数据只倒了一次
class MyStack {private Deque<Integer> queue1;private Deque<Integer> queue2;public MyStack() {queue1 = new LinkedList<Integer>();queue2 = new LinkedList<Integer>();}public void push(int x) {queue2.offer(x);while(!queue1.isEmpty()){queue2.offer(queue1.poll());}Deque<Integer> tempQ = queue1;queue1 = queue2;queue2 = tempQ;}public int pop() {return queue1.poll();}public int top() {return queue1.peek();}public boolean empty() {return queue1.isEmpty();}
}

20.有效的括号

题目的描述:

交错的括号不能出现,但是包含的括号可以出现,例如:[(]) 是 false,但是 [()] 是 true

解法:

  • 当遇到左括号的时候入栈
  • 当遇到右括号的时候,取出栈顶元素,判断能否与右括号匹配

注意:

  • 简化代码的方法,遇到左括号,存对应的右括号
  • 到时候遇到右括号,需要判断栈顶和右括号是否匹配的时候,直接判断是否相等就行,而不用三个分别判断
class Solution {public boolean isValid(String s) {Deque<Character> stack = new ArrayDeque<>();for(int i = 0; i < s.length(); ++ i){char ch = s.charAt(i);if(ch == '(') stack.push(')');else if(ch == '{') stack.push('}');else if(ch == '[') stack.push(']');else if(stack.isEmpty() || stack.pop() != ch){return false;}}if(!stack.isEmpty()){return false;}return true;}
}

我的代码

class Solution {public boolean isValid(String s) {Deque<Character> stack = new ArrayDeque<>();for(int i = 0; i < s.length(); ++ i){char ch = s.charAt(i);if(ch == ')' || ch == '}' || ch == ']'){if(stack.isEmpty()){return false;}char top = stack.peek();if((top == '(' && ch == ')') || (top == '{' && ch == '}')|| (top == '[' && ch == ']')){stack.pop();}else{return false;}}else{stack.push(ch);}}if(!stack.isEmpty()){return false;}return true;}
}

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

括号匹配的另一种描述形式

可以用StringBuilder简化代码,字符串本身提供删除指定索引位置的API:

class Solution {public String removeDuplicates(String s) {StringBuilder sb = new StringBuilder();for (char c : s.toCharArray()) {if (sb.length() != 0 && sb.charAt(sb.length() - 1) == c) {sb.deleteCharAt(sb.length() - 1);} else {sb.append(c);}}return sb.toString();}
}
class Solution {public String removeDuplicates(String s) {Deque<Character> stack = new ArrayDeque<>();for(int i = 0; i < s.length(); ++ i){char ch = s.charAt(i);if(stack.isEmpty() || stack.peek() != ch){stack.push(ch);}else{stack.pop();}}char[] ans = new char[stack.size()];int idx = stack.size() - 1;while(!stack.isEmpty()){ans[idx--] = stack.pop();}return new String(ans);}
}

150.逆波兰表达式求值

  • 遇到运算符则从栈顶取两个数字出来,第一个数字是运算符右边的,第二个才是左边的,然后根据运算符的类型,把计算结果存回栈中,便于后续的计算
  • 如果遇到数字,就存入栈中,等待后续被取出
class Solution {public int evalRPN(String[] tokens) {Deque<Integer> stack = new ArrayDeque<>();for(int i = 0; i < tokens.length; ++ i){String token = tokens[i];if(token.equals("+") || token.equals("-") || token.equals("*") || token.equals("/")){int r = stack.pop();int l = stack.pop();if(token.equals("+")) stack.push(l+r);else if(token.equals("-")) stack.push(l-r);else if(token.equals("*")) stack.push(l*r);else stack.push(l/r);}else{stack.push(Integer.parseInt(token));}}return stack.pop();}
}

239.滑动窗口最大值

动态维护一个保持下标序列的递减队列

  • 窗口要退出一个元素:
    • 这个元素可能早已出队
    • 也可能正是当前队列的最大值(队首),如果是队首就需要出队了
  • 当新加入一个元素时,
    • 如果这个元素比队尾的值大,则说明这个元素的“价值”更高。
    • 因为这个元素不仅更偏右边,而且更大,那么之前那些存在队列中比这个元素小的值就都可以从队尾出队了

注意:

  • poll 是从队首出队
  • pollLast 从队尾出队
  • offer 是从队尾入队,等同于 offerLast
class Solution {public int[] maxSlidingWindow(int[] nums, int k) {Deque<Integer> queue = new LinkedList<>();int[] ans = new int[nums.length - k + 1];int idx = 0;for(int i = 0; i < k; ++ i){while(!queue.isEmpty() && nums[queue.peekLast()] <= nums[i]){queue.pollLast();}queue.offerLast(i);}ans[idx++] = nums[queue.peekFirst()];for(int i = k; i < nums.length; ++ i){if(queue.peekFirst() == i - k) queue.poll();while(!queue.isEmpty() && nums[queue.peekLast()] <= nums[i]){queue.pollLast();}queue.offerLast(i);ans[idx++] = nums[queue.peekFirst()];}return ans;}
}

347.前 K 个高频元素

求前 K 个最大 的元素:

  • 用优先队列维护一个size为k的最小堆,这样最小的元素保持在堆顶
  • 当有新元素来的时候
    • 如果新元素大于堆顶的最小元素,说明这个堆顶的元素要被淘汰掉,新元素加入堆中
    • 如果新元素小于堆顶元素,说明新元素连最小的元素都打不过,自然堆中的元素是当前最大的K个,堆保持不变
class Solution {public int[] topKFrequent(int[] nums, int k) {Map<Integer, Integer> table = new HashMap<>();for(int i = 0; i < nums.length; ++ i){table.put(nums[i], table.getOrDefault(nums[i], 0) + 1);}int[] ans = new int[k];PriorityQueue<Integer> pq = new PriorityQueue<>((Integer a, Integer b)->{return table.get(a) - table.get(b); });for(int key : table.keySet()){if(pq.size() < k){pq.add(key);}else if(table.get(pq.peek()) < table.get(key)){pq.poll();pq.add(key);}}int idx = 0;while(!pq.isEmpty()){ans[idx++] = pq.poll();}return ans;}
}

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

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

相关文章

计算机视觉——手机目标检测数据集

这是一个手机目标检测的数据集&#xff0c;数据集的标注工具是labelimg,数据格式是voc格式&#xff0c;要训练yolo模型的话&#xff0c;可以使用脚本改成txt格式&#xff0c;数据集标注了手机&#xff0c;标签名&#xff1a;telephone,数据集总共有1960张&#xff0c;有一部分是…

软件无线电安全之GNU Radio基础 -上

GNU Radio介绍 GNU Radio是一款开源的软件工具集&#xff0c;专注于软件定义无线电&#xff08;SDR&#xff09;系统的设计和实现。该工具集支持多种SDR硬件平台&#xff0c;包括USRP、HackRF One和RTL-SDR等。用户可以通过GNU Radio Companion构建流程图&#xff0c;使用不同…

BackTrader 中文文档(二十七)

原文&#xff1a;www.backtrader.com/ 数据 - 多个时间框架 原文&#xff1a;www.backtrader.com/blog/posts/2015-08-24-data-multitimeframe/data-multitimeframe/ 有时&#xff0c;使用不同的时间框架进行投资决策&#xff1a; 周线用于评估趋势 每日执行进入 或者 5 分钟…

软考132-上午题-【软件工程】-沟通路径

一、定义 1-1、沟通路径1 沟通路径 1-2、沟通路径2 沟通路径 n-1 二、真题 真题1&#xff1a; 真题2&#xff1a; 真题3&#xff1a;

发布 Chrome/Edge浏览器extension扩展到应用商店

Chrom Extension发布流程 创建和发布自定义 Chrome 应用和扩展程序&#xff1a;https://support.google.com/chrome/a/answer/2714278?hlzh-Hans 在 Chrome 应用商店中发布&#xff1a;https://developer.chrome.com/docs/webstore/publish?hlzh-cn 注册开发者帐号&#…

图解CPU的实模式与保护模式

哈喽&#xff0c;大家好&#xff0c;我是呼噜噜&#xff0c;好久没有更新old linux了&#xff0c;在上一篇文章Linux0.12内核源码解读(7)-陷阱门初始化中&#xff0c;我们简要地提及了中断&#xff0c;但是中断机制在计算机世界里非常重要&#xff0c;处处都离不开中断&#xf…

Element——组件

element官网 https://element.eleme.cn/#/zh-CN/component/layout vscode格式化快捷键&#xff1a;shiftaltf table表格 <template><el-table:data"tableData"style"width: 100%"><el-table-columnprop"date"label"日期…

Git使用总结(不断更新中)

branch 本地分支操作 删除本地分支 git branch -d <local-branch-name>远端分支操作 从远端分支创建本地分支 git checkout -b <local-branch-name> origin/<remote-branch-name>git ignore 如果工程的代码文件中有不希望上传到远端的文件&#xff0c;…

排列特征重要性(Permutation Feature Importance)

5个条件判断一件事情是否发生&#xff0c;每个条件可能性只有2种&#xff08;发生或者不发生&#xff09;&#xff0c;计算每个条件对这件事情发生的影响力。排列特征重要性模型的程序。 例一 在机器学习领域&#xff0c;排列特征重要性&#xff08;Permutation Feature Impor…

【honggfuzz学习笔记】honggfuzz的基本特性

本文架构 1.动机2.honggfuzz的基本概念官网描述解读 3. honggfuzz的反馈驱动(Feedback-Driven)软件驱动反馈&#xff08;software-based coverage-guided fuzzing&#xff09;代码覆盖率代码覆盖率的计量单位 代码覆盖率的统计方式 硬件驱动反馈&#xff08; hardware-based co…

CTFHUB RCE作业

题目地址&#xff1a;CTFHub 完成情况如图&#xff1a; 知识点&#xff1a; preg_match_all 函数 正则匹配函数 int preg_match_all ( string $pattern , string $subject [, array &$matches [, int $flags PREG_PATTERN_ORDER [, int $offset 0 ]]] )搜索 subject 中…

【Python小游戏】植物大战僵尸的实现与源码分享

文章目录 Python版植物大战僵尸环境要求方法源码分享初始化页面&#xff08;部分&#xff09;地图搭建&#xff08;部分&#xff09;定义植物类 &#xff08;部分&#xff09;定义僵尸类&#xff08;部分&#xff09;游戏运行入口 游戏源码获取 Python版植物大战僵尸 已有的植…

【Proteus】51单片机对直流电机的控制

直流电机&#xff1a;输出或输入为直流电能的旋转电机。能实现直流电能和机械能互相转换的电机。把它作电动机运行时是直流电动机&#xff0c;电能转换为机械能&#xff1b;作发电机运行时是直流发电机&#xff0c;机 械能转换为电能。 直流电机的控制&#xff1a; 1、方向控制…

动态多目标测试函数DF1-DF14,FDA1-FDA5,SDP1-SDP12的TurePOF(MATLAB代码)

动态多目标测试函数FDA1、FDA2、FDA3、FDA4、FDA5的turePOF&#xff08;MATLAB代码&#xff09; 动态多目标测试函数DF1-DF14的turePOF变化&#xff08;提供MATLAB代码&#xff09; 动态多目标测试函数SDP1-SDP12的TurePOF变化视频&#xff08;含MATLAB代码及参考文献&#xff…

Java Swing制作大鱼吃小鱼魔改版本

《大鱼吃小鱼》这款游戏的历史渊源可以追溯到休闲游戏的兴起和发展。在游戏的早期发展阶段&#xff0c;开发者们开始探索各种简单而有趣的游戏玩法&#xff0c;以吸引玩家的注意力。在这样的背景下&#xff0c;《大鱼吃小鱼》应运而生&#xff0c;它结合了自然界的食物链原理与…

AI大模型之idea通义灵码智能AI插件安装方式

问题描述 主要讲述如何进行开发工具 idea中如何进行通义灵码的插件的安装解决方案 直接在idea的plugin市场中安装 下载插件之后进行安装 见资源

lua 光速入门

文章目录 安装注释字符串变量逻辑运算条件判断循环函数Table (表)常用全局函数模块化 首先明确 lua 和 js Python一样是动态解释性语言&#xff0c;需要解释器执行。并且不同于 Python 的强类型与 js 的弱类型&#xff0c;它有点居中&#xff0c;倾向于强类型。 安装 下载解释…

【OpenHarmony】TDD-FUZZ环境配置

零、参考 1、AttributeError: ‘ElementTree‘ object has no attribute ‘getiterator‘&#xff1a;https://blog.csdn.net/suhao0911/article/details/110950742 一、创建工作目录 1、新建工作目录如&#xff1a;D:\0000_TDD_FUZZ\0000_ohos_tdd_fuzz。 2、gitee上下载 t…

陇剑杯 ios 流量分析 CTF writeup

陇剑杯 ios 流量分析 链接&#xff1a;https://pan.baidu.com/s/1KSSXOVNPC5hu_Mf60uKM2A?pwdhaek 提取码&#xff1a;haek目录结构 LearnCTF ├───LogAnalize │ ├───linux简单日志分析 │ │ linux-log_2.zip │ │ │ ├───misc日志分析 │ │…

html+vue编写分页功能

效果&#xff1a; html关键代码&#xff1a; <div class"ui-jqgrid-resize-mark" id"rs_mlist_table_C87E35BE"> </div><div class"list_component_pager ui-jqgrid-pager undefined" dir"ltr"><div id"pg…