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

Collection与数据结构 Stack与Queue(一): 栈与Stack

1. 栈

1.1 概念

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶
出栈:栈的删除操作叫做出栈。出数据在栈顶
在这里插入图片描述
栈在现实生活中的例子:
弹夹:
在这里插入图片描述
羽毛球筒:
在这里插入图片描述

1.2 栈的使用

方法功能
Stack()构造一个空的栈
E push(E e)将e入栈,并返回e
E pop()将栈顶元素出栈并返回
E peek()获取栈顶元素
int size()获取栈中有效元素个数
boolean empty()检测栈是否为空
import java.util.Stack;public class Main {public static void main(String[] args) {//使用Stack中自带的方法Stack<Integer> stack = new Stack<>();stack.push(1);stack.push(2);stack.push(3);stack.push(4);//压栈System.out.println(stack.peek());System.out.println(stack.peek());//没有弹出元素,只是返回了栈顶元素System.out.println(stack.pop());System.out.println(stack.pop());//出栈System.out.println(stack.size());//计算栈中元素的个数System.out.println(stack.empty());//判断栈是否为空//使用Stack从Collection继承下来的方法Stack<Integer> stack1 = new Stack<>();stack1.add(1);stack1.add(2);stack1.add(3);stack1.add(4);//添加元素System.out.println(stack1.isEmpty());//判断是否为空}
}

运行结果:
在这里插入图片描述

1.3 栈的模拟实现

import java.util.Arrays;public class MyStack {int[] array = new int[5];//默认容积为5int size;public void push(int x){ensureCapacity();array[size] = x;size++;}public int pop(){int e = peek();size--;return e;}public int peek(){if (!empty()){return array[size-1];}throw new EmptyExecption("Stack is empty.");}public boolean empty(){if (size == 0){return true;}return false;}public int size(){return this.size;}private void ensureCapacity(){if (this.array.length == size){this.array = Arrays.copyOf(array,array.length*2);}}
}
public class EmptyExecption extends RuntimeException{public EmptyExecption(String message) {super(message);}
}

2. 栈的相关面试题

2.1 括号匹配

OJ链接
在这里插入图片描述

class Solution {public boolean isValid(String s) {Stack<Character> stack = new Stack<>();for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);if (c == '(' || c == '[' || c == '{') {stack.push(c);//左括号入栈}else {if (stack.empty()){return false;//如果在匹配的时候,栈为空,说明右括号赘余}char ch2 = stack.peek();if (ch2 == '(' && c == ')'||ch2 == '[' && c == ']'||ch2 == '{' && c == '}'){stack.pop();}else {return false;//括号不匹配}}}return stack.empty();//遍历完了,栈中还有元素,说明左括号赘余}}

上述代码逻辑较为复杂,我们通过一张图来理清楚:
在这里插入图片描述

2.2 逆波兰表达式求值

OJ链接
在这里插入图片描述

class Solution2 {public int evalRPN(String[] tokens) {Stack<Integer> stack = new Stack<>();for (int i = 0; i < tokens.length; i++) {String s = tokens[i];if (isOperation(s)){int x1 = stack.pop();int x2 = stack.pop();//把两个数字出栈int x = 0;if (s.equals("+")){x = x1+x2;} else if (s.equals("-")) {x = x2-x1;//注意逆波兰表达式,先从栈中弹出的放在后面} else if (s.equals("/")) {x = x2/x1;}else {x = x1*x2;}stack.push(x);//计算之后放回栈中}else {stack.push(Integer.parseInt(s));//将字符串转化为数字}}return stack.pop();//最后栈中的值就是最终的值}private boolean isOperation(String s){//判断是否为加减乘除if (s.equals("+") ||s.equals("-")||s.equals("*")||s.equals("/")){return true;}return false;}}

拓展: 中缀表达式转后缀表达式,现给出中缀表达式( 1 + 2 ) * ( 3 + 4 ),转为后缀(逆波兰)表达式过程如下.
在这里插入图片描述
其实我们在电脑中或者是手机上经常用到的计算器就是这样的原理.计算机中的计算器是无法直接识别中缀表达式的,都是先转为后缀表达式,再进行运算的.

在这里插入图片描述

2.3 入栈出栈顺序匹配

OJ链接

在这里插入图片描述

class Solution3 {public boolean validateStackSequences(int[] pushed, int[] popped) {Stack<Integer> stack = new Stack<>();int j = 0;for (int i = 0; i < pushed.length; i++) {stack.push(pushed[i]);while (!stack.empty() &&stack.peek() == popped[j]){//每放入栈中一个元素,就和popped比较是否相等stack.pop();//如果相等,出栈j++;//popped下标向后走}}while (j < popped.length){//i把push全部遍历完之后,Stack中可能还有元素没有与popped中的匹配完成if (stack.peek() == popped[j]){stack.pop();j++;//继续匹配操作}else {return false;//一旦有一个不匹配,说明popped的出栈顺序是错误的}}return true;//全部匹配完成,返回true}}

2.4 在常数时间复杂度的情况下寻找栈中最小元素

OJ链接

在这里插入图片描述

class MinStack {Stack<Integer> stack;Stack<Integer> stack1;public MinStack() {stack = new Stack<>();//放所有要入栈的元素stack1 = new Stack<>();//放较小元素,栈顶元素是入stack所有元素中最小的}public void push(int val) {stack.push(val);if (stack1.empty()){//如果最小栈中没有元素,就把第一个元素放入stack1.push(val);}else{if(stack1.peek() >= val){//和最小栈的栈顶元素比较大小,stack1的栈顶大于等于val的时候,入栈//等于的时候也要放入,否则pop的时候,最小栈和普通栈会不匹配stack1.push(val);}}}public void pop() {if (Objects.equals(stack.pop(), stack1.peek())){stack1.pop();//两栈元素相等的时候都弹出,否则只弹出普通栈中的元素}}public int top() {return stack.peek();//返回普通栈栈顶元素}public int getMin() {return stack1.peek();//直接返回最小栈的栈顶元素}}

2.5 逆序打印列表

方法一:递归法

void printList(Node head){if(null != head){//遇到null的时候往回递归printList(head.next);//没有遇到null的时候,向后递归System.out.print(head.val + " ");}
}

图解:
在这里插入图片描述

方法二:Stack法

 Stack<Node> s = new Stack<>();// 将链表中的结点保存在栈中Node cur = head;while(null != cur){s.push(cur);cur = cur.next;}// 将栈中的元素出栈while(!s.empty()){System.out.print(s.pop().val + " ");}
}

从上述代码,我们可以得到一个结论,栈可以替代递归思想,在我们后期学习二叉树的时候,在非递归遍历二叉树的时候,我们会频繁地用到栈.

相关文章:

Collection与数据结构 Stack与Queue(一): 栈与Stack

1. 栈 1.1 概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 压栈&…...

内部类(来自类和对象的补充)

❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; hellohello~&#xff0c;大家好&#x1f495;&#x1f495;&#xff0c;这里是E绵绵呀✋✋ &#xff0c;如果觉得这篇文章还不错的话还请点赞❤️❤️收藏&#x1f49e; &#x1f49e; 关注&#x1f4a5;&a…...

Android 高德地图

1.获取Key 进入高德开放平台控制台&#xff0c;创建一个新应用。在创建的应用上点击"添加key"按钮&#xff0c;在弹出的对话框中&#xff0c;依次输入key名称&#xff0c;选择服务平台为“Android平台”&#xff0c;输入发布版安全码 SHA1、以及 Package。 获取 S…...

代码随想录|Day31|贪心06|738.单调递增的数字

738.单调递增的数字 思路&#xff1a; 1. 从右向左遍历 从字符串的最后一位向前遍历&#xff0c;即从低位到高位进行检查。这是因为当我们修改某一位数字时&#xff0c;可能会影响到更低位的数字。 2. 检查并修改数字 在遍历过程中&#xff0c;如果发现当前位数字小于其前一位&…...

机械制造学习笔记

一、切削加工、切削运动的基本概念及刀具切削过程 切削加工&#xff1a; 定义&#xff1a;切削加工是利用切削刀具对工件进行切削&#xff0c;以去除多余材料并得到所需形状和尺寸的加工方法之一。应用&#xff1a;广泛应用于金属加工、木材加工、塑料加工等领域&#xff0c;是…...

Golang | Leetcode Golang题解之第3题无重复字符的最长子串

题目&#xff1a; 题解&#xff1a; func lengthOfLongestSubstring(s string) int {// 哈希集合&#xff0c;记录每个字符是否出现过m : map[byte]int{}n : len(s)// 右指针&#xff0c;初始值为 -1&#xff0c;相当于我们在字符串的左边界的左侧&#xff0c;还没有开始移动r…...

SWM341系列应用(上位机应用)

SWM341系列之上位机应用 1、分级图像和PNG、JPG的应用 现象&#xff1a;客户使用SWM34SVET6HMI_0.4.1版本上位机进行UI界面布局&#xff0c;反馈在模拟运行时&#xff08;PC端&#xff09;流畅&#xff0c;在Demo平台&#xff08;设备端&#xff09;运行卡顿。 分析及解决&…...

【软件工程】详细设计(一)

1. 引言 1.1 编写目的 该文档的目的是描述《学生成绩管理系统》项目的详细设计&#xff0c;其主要内容包括&#xff1a; 系统功能简介 系统详细设计简述 各个模块的实现逻辑 最小模块组件的伪代码 本文档的预期的读者是&#xff1a; 开发人员 项目管理人员 测试人员 …...

【AIGC】如何在Windows/Linux上部署stable diffusion

文章目录 整体安装步骤windows10安装stable diffusion环境要求安装步骤注意事项参考博客其他事项安装显卡驱动安装cuda卸载cuda安装对应版本pytorch安装git上的python包Q&A linux安装stable diffusion安装anaconda安装cudagit 加速配置虚拟环境挂载oss&#xff08;optional…...

基于java实现的弹幕视频网站

开发语言&#xff1a;Java 框架&#xff1a;ssm 技术&#xff1a;JSP JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclip…...

【大数据存储】实验4 NoSQL数据库

实验4 NoSQL数据库 NoSQL数据库的安装和使用实验环境&#xff1a; Ubuntu 22.04.3 Jdk 1.8.0_341 Hadoop 3.2.3 Hbase 2.4.17 Redis 6.0.6 mongdb 6.0.12 mogosh 2.1.0 Redis 安装redis完成 新建终端启动redisredis-server新建一个终端redis-cli 建表操作 尝…...

从零学算法80

80. 删除有序数组中的重复项 II 给你一个有序数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使得出现次数超过两次的元素只出现两次 &#xff0c;返回删除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须在 原地 修改输入数组 并在使用 O(1) 额外…...

Jupyter notebook文件默认存储路径以及更改方法

初次使用Jupyter Notebook&#xff0c;确实好用啊&#xff01;但安装Anaconda后&#xff0c;打开Jupyter Notebook 的时候&#xff0c;新建文件的默认存储路径一般在C系统盘下面的XXX目录&#xff0c;那么路径是什么呢&#xff1f;我想把文件保存到其他的文件夹下应该怎么做呢&…...

WPF中通过自定义Panel实现控件拖动

背景 看到趋时软件的公众号文章&#xff08;WPF自定义Panel&#xff1a;让拖拽变得更简单&#xff09;&#xff0c;发现可以不通过Drag的方法来实现ListBox控件的拖动&#xff0c;而是通过对控件的坐标相加减去实现控件的位移等判断&#xff0c;因此根据文章里面的代码,边理解边…...

Centos7安装Docker与Docker-compose【图文教程】

个人记录 查看一下系统是否已经安装了Docker yum list installed | grep docker如下图代表没有安装Docker 卸载已有Docker yum remove docker docker-common docker-selinux docker-engine切换目录 cd /etc/yum.repos.d/查看当前目录所有的镜像源 ll安装yum-util与devi…...

mac电脑maven配置环境变量

1、下载maven https://maven.apache.org 2、配置环境变量 vim .bash_profile JAVA_HOME/Library/Java/JavaVirtualMachines/jdk-1.8.jdk/Contents/Home PATH$JAVA_HOME/bin:$PATH export JAVA_HOME export PATH#maven export MAVEN_HOME/Users/haines/desktop/work/java/a…...

后端返还二进制excl表格数据时候,如何实现在前端下载表格功能及出现表格打开失败的异常处理。

背景&#xff1a; 后端返还一个二进制流的excl表格数据&#xff0c;前端需要对其解析&#xff0c;然后可提供给客户进行下载。 思路&#xff1a;把二进制流数据转换给blob对象&#xff0c;然后利用a标签进行前端下载。 代码&#xff1a; 后端返还 类似如下的数据 前端代码…...

搞学术研究好用免费的学术版ChatGPT网站-学术AI

学术版ChatGPThttps://chat.uaskgpt.com/mobile/?user_sn88&channelcsdn&scenelogin 推荐一个非常适合中国本科硕士博士等学生老师使用的学术版ChatGPT&#xff0c; 对接了超大型学术模型&#xff0c;利用AI技术实现学术润色、中英文翻译&#xff0c;学术纠错&#…...

vue3从精通到入门9:计算属性computed

在 Vue 3 中&#xff0c;computed 是一个用于创建计算属性的工具&#xff0c;它基于组件的响应式依赖进行复杂的计算&#xff0c;并返回一个新的响应式引用。计算属性是 Vue 的一个核心概念&#xff0c;它提供了一种声明式的方式来执行基于其依赖的响应式数据的计算。 compute…...

kafka面试常见问题

1、如何判断kafka某个主题消息堆积&#xff1f; 要判断Kafka中某个主题的消息是否堆积&#xff0c;可以通过查看该主题的生产者和消费者的偏移量&#xff08;offset&#xff09;差异来实现。Kafka中的每条消息在主题的分区内都有一个唯一的偏移量&#xff0c;生产者每发送一条…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...