代码随想录 Day8 栈(FILO)与队列(FIFO) LeetCode T232 用栈实现队列 LeetCodeT225 用队列实现栈

 题目详细思路来自于:代码随想录 (programmercarl.com)

栈和队列都是大家不陌生的数据结构,我们之前的栈和队列一般是用数组或链表来实现的 ,

这里我们给出实现方式,用于帮助更好的理解.

1.用链表实现栈 

/* 基于链表实现的栈 */
class LinkedListStack {
private ListNode stackPeek; // 将头节点作为栈顶private int stkSize = 0; // 栈的长度
public LinkedListStack() {stackPeek = null;
}
/* 获取栈的长度 */
public int size() {return stkSize;
}
/* 判断栈是否为空 */
public boolean isEmpty() {return size() == 0;
}
/* 入栈 */
public void push(int num) {ListNode node = new ListNode(num);node.next = stackPeek;stackPeek = node;stkSize++;
}
/* 出栈 */
public int pop() {int num = peek();stackPeek = stackPeek.next;stkSize--;return num;
}
/* 访问栈顶元素 */
public int peek() {if (size() == 0)throw new IndexOutOfBoundsException();return stackPeek.val;
}
/* 将 List 转化为 Array 并返回 */
public int[] toArray() {ListNode node = stackPeek;int[] res = new int[size()];for (int i = res.length - 1; i >= 0; i--) {res[i] = node.val;node = node.next;}return res;}
}

 2.用数组实现栈

class ArrayStack {private ArrayList<Integer> stack;public ArrayStack() {
// 初始化列表(动态数组)stack = new ArrayList<>();
}
/* 获取栈的长度 */
public int size() {return stack.size();
}
/* 判断栈是否为空 */
public boolean isEmpty() {return size() == 0;
}
/* 入栈 */
public void push(int num) {stack.add(num);
}
/* 出栈 */
public int pop() {if (isEmpty())throw new IndexOutOfBoundsException();return stack.remove(size() - 1);
}
/* 访问栈顶元素 */
public int peek() {if (isEmpty())throw new IndexOutOfBoundsException();return stack.get(size() - 1);
}
/* 将 List 转化为 Array 并返回 */
public Object[] toArray() {return stack.toArray();}
}

 3.两种实现的优缺点

3.1 用数组实现栈的优缺点

在基于数组的实现中,入栈和出栈操作都是在预先分配好的连续内存中进行,具有很好的缓存本地性,因此效率较高。然而,如果入栈时超出数组容量,会触发扩容机制,导致该次入栈操作的时间复杂度变为 𝑂(𝑛).

 

3.2 用链表实现栈的优缺点

在链表实现中,链表的扩容非常灵活,不存在上述数组扩容时效率降低的问题。但是,入栈操作需要初始化节点对象并修改指针,因此效率相对较低。不过,如果入栈元素本身就是节点对象,那么可以省去初始化步骤,从而提高效率。

4. 用链表实现队列

class LinkedListQueue {private ListNode front, rear; // 头节点 front ,尾节点 rearprivate int queSize = 0;
public LinkedListQueue() {front = null;rear = null;
}
/* 获取队列的长度 */
public int size() {return queSize;
}
/* 判断队列是否为空 */
public boolean isEmpty() {return size() == 0;
}
/* 入队 */
public void push(int num) {
// 尾节点后添加 numListNode node = new ListNode(num);
// 如果队列为空,则令头、尾节点都指向该节点if (front == null) {front = node;rear = node;
// 如果队列不为空,则将该节点添加到尾节点后} else {rear.next = node;rear = node;}queSize++;
}
/* 出队 */
public int pop() {int num = peek();
// 删除头节点front = front.next;queSize--;return num;
}
/* 访问队首元素 */
public int peek() {if (size() == 0)throw new IndexOutOfBoundsException();return front.val;
}
/* 将链表转化为 Array 并返回 */
public int[] toArray() {ListNode node = front;int[] res = new int[size()];for (int i = 0; i < res.length; i++) {res[i] = node.val;node = node.next;}return res;}
}

5.用数组实现队列

你可能会发现一个问题:在不断进行入队和出队的过程中, front 和 rear 都在向右移动, 当它们到达数组尾部时就无法继续移动了。为解决此问题,我们可以将数组视为首尾相接的“环形数组”。对于环形数组,我们需要让 front 或 rear 在越过数组尾部时,直接回到数组头部继续遍历。这种周期性规律可以通过“取余操作”来实现

/* 基于环形数组实现的队列 */
class ArrayQueue {private int[] nums; // 用于存储队列元素的数组private int front; // 队首指针,指向队首元素private int queSize; // 队列长度
public ArrayQueue(int capacity) {nums = new int[capacity];front = queSize = 0;
}
/* 获取队列的容量 */
public int capacity() {return nums.length;
}
/* 获取队列的长度 */
public int size() {return queSize;
}
/* 判断队列是否为空 */
public boolean isEmpty() {return queSize == 0;
}
/* 入队 */
public void push(int num) {if (queSize == capacity()) {System.out.println(" 队列已满");return;
}
// 计算尾指针,指向队尾索引 + 1
// 通过取余操作,实现 rear 越过数组尾部后回到头部int rear = (front + queSize) % capacity();
// 将 num 添加至队尾nums[rear] = num;queSize++;
}
/* 出队 */
public int pop() {int num = peek();
// 队首指针向后移动一位,若越过尾部则返回到数组头部front = (front + 1) % capacity();queSize--;return num;
}
/* 访问队首元素 */
public int peek() {if (isEmpty())throw new IndexOutOfBoundsException();return nums[front];
}
/* 返回数组 */
public int[] toArray() {
// 仅转换有效长度范围内的列表元素int[] res = new int[queSize];for (int i = 0, j = front; i < queSize; i++, j++) {res[i] = nums[j % capacity()];}return res;}
}

LeetCode T232 用栈实现队列

题目链接:

232. 用栈实现队列 - 力扣(LeetCode) 

题目思路:

我们这里就要用两个栈来实现队列,一个是stackOut,一个是stackIn,in栈负责将要入队的添加进来,但是这时候我们发现出栈的话会和队列的出队顺序相反,所以我们再入栈一次,这样出栈的顺序就颠倒过来啦,也完美的实现队列的基本功能.

注:一定要将In栈的全部元素一起push进Out栈,否则顺序可能会发生变化,这样就影响了正常的出栈功能.

题目代码:

class MyQueue {Stack<Integer> stackIn;Stack<Integer> stackOut;public MyQueue() {stackIn = new Stack<>();stackOut = new Stack<>();}public void push(int x) {stackIn.push(x);}public int pop() {downStackIn();return stackOut.pop();}public int peek() {downStackIn();return stackOut.peek();}public boolean empty() {downStackIn();return stackOut.isEmpty();}public void downStackIn(){while(!stackOut.isEmpty()){return;}while(!stackIn.isEmpty()){stackOut.push(stackIn.pop());}}
}/*** Your MyQueue object will be instantiated and called as such:* MyQueue obj = new MyQueue();* obj.push(x);* int param_2 = obj.pop();* int param_3 = obj.peek();* boolean param_4 = obj.empty();*/

LeetCode T225 用队列实现栈

题目链接:225. 用队列实现栈 - 力扣(LeetCode)

题目思路:

这里我们同样可以用和上一题同样的思路实现,但是为了更有挑战性,我们决定用一个队列来实现栈,假设我们入队元素是123,此时我们需要的出队元素应该是3,那么我们该如何操作呢,其实,我们只需要让前两个元素重新入队,这样第一个出队的元素就是3了,其实就是前size()-1个元素重新入队,就实现了出栈的操作

这里我使用的是deque,这个类可以实现两天的操作,就是比queue多了两头操作的一些方法.

题目代码:

class MyStack {Deque<Integer> que1;public MyStack() {que1 = new ArrayDeque<>();}public void push(int x) {que1.addLast(x);}public int pop() {int tmp = que1.size()-1;while(tmp>0){que1.addLast(que1.peekFirst());que1.pollFirst();tmp--;}return que1.pollFirst();}public int top() {return que1.peekLast();}public boolean empty() {return que1.isEmpty();}
}/*** Your MyStack object will be instantiated and called as such:* MyStack obj = new MyStack();* obj.push(x);* int param_2 = obj.pop();* int param_3 = obj.top();* boolean param_4 = obj.empty();*/

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

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

相关文章

聊聊MySQL的InnoDB引擎与MVCC

目录 一、InnoDB引擎 1.1逻辑存储结构 1). 表空间 2). 段 3). 区 4). 页 5). 行 1.2架构 1.2.1内存结构 1). Buffer Pool 2). Change Buffer 3). Adaptive Hash Index 4). Log Buffer 1.2.2磁盘结构 1). System Tablespace 2). File-Per-Table Tablespaces 3). …

Vue3之Suspense

<Suspense> 是一个内置组件&#xff0c;用来在组件树中协调对异步依赖的处理。它让我们可以在组件树上层等待下层的多个嵌套异步依赖项解析完成&#xff0c;并可以在等待时渲染一个加载状态。 我们可以看到官网并不推荐我们使用它&#xff0c;目前仍处于测试中。 他用于加…

VUE2项目:尚品汇-axios二次封装请求以及VUEX的状态管理库

上一篇&#xff1a;VUE2项目&#xff1a;尚品汇VUE-CLI脚手架初始化项目以及路由组件分析&#xff08;一&#xff09; 目录 axios二次封装API接口管理与解决跨域API接口管理nprogress进度条配置 VUEX状态管理库三级分类动态背景颜色防抖三级联动跳转路由分析 axios二次封装 项…

windows系统查看exe程序的依赖dll并拷贝到指定路径下

脚本 echo off REM windows_copy_depends.bat是脚本文件名&#xff0c;exe_path是exe文件的全路径&#xff0c;dll_folder_path是脚本当前路径下的文件夹名称 REM 如windows_copy_depends.bat E:\git_code\windows_docker_desktop\winget.exe 123 echo Usage: windows_copy_dep…

大数据-玩转数据-Flink Catalog

一、Catalog Catalog 提供了元数据信息&#xff0c;例如数据库、表、分区、视图以及数据库或其他外部系统中存储的函数和信息。 数据处理最关键的方面之一是管理元数据。 元数据可以是临时的&#xff0c;例如临时表、或者通过 TableEnvironment 注册的 UDF。 元数据也可以是持…

ES写入数据时:circuit_breaking_exception[[parent] Data too large

报错&#xff1a; circuit_breaking_exception[[parent] Data too large, data for [<transport_request>] would be [12318476937/11.2gb], which is larger than the limit of [12237372108/12.2gb], real usage: [12318456248/11.2gb]原因&#xff1a; &#xff08;…

Kafka收发消息核心参数详解

文章目录 1、从基础的客户端说起1.1、消息发送者主流程1.2、消息消费者主流程 2、从客户端属性来梳理客户端工作机制2.1、消费者分组消费机制 1、从基础的客户端说起 Kafka提供了非常简单的客户端API。只需要引入一个Maven依赖即可&#xff1a; <dependency><groupId…

【RabbitMQ实战】06 RabbitMQ配置

一、概述 一般情况下&#xff0c;可以使用默认的内建配置来有效地运行RabbitMQ&#xff0c;并且大多数情况下也并不需要修改任何 RabbitMQ的配置。当然&#xff0c;为了更加有效地操控 RabbitMQ&#xff0c;也可以利用调节系统范围内的参数来达到定制化的需求。 RabbitMQ提供…

《大师级引导-应对困境的工具与技术》读书笔记1

《大师级引导-应对困境的工具与技术》这个书&#xff0c;十分不错&#xff0c;教练和非教练都可以学习。下面是其中的关于冲突的处理&#xff1a; 定义&#xff1a;双方以解决冲突、说明关系为目的而进行的积极的、具有建设性的对话。 目的&#xff1a;制定双方协议&#xf…

《CTFshow-Web入门》10. Web 91~110

Web 入门 索引web91题解总结 web92题解总结 web93题解 web94题解 web95题解 web96题解 web97题解 web98题解 web99题解总结 web100题解 web101题解 web102题解 web103题解 web104题解 web105题解总结 web106题解 web107题解 web108题解 web109题解 web110题解 ctf - web入门 索…

锚框_的标定

一、查漏补缺、熟能生巧&#xff1a; 1.关于fix.axis.add_patch在原来图像的坐标系同添加 边框的函数的使用&#xff1a; 2.torch.arange( h , device)生成tensor的等差数组: 3.torch.T&#xff08;&#xff09;就是transpose转置操作的函数咯: 4.torch.repeat操作&#xff0c…

Substructure‑aware subgraph reasoning for inductive relation prediction

摘要 关系预测的目的是推断知识图中实体之间缺失的关系,其中归纳关系预测因其适用于新兴实体的有效性而广受欢迎。大多数现有方法学习逻辑组合规则或利用子图来预测缺失关系。尽管在性能方面已经取得了很大的进展,但目前的模型仍然不是最优的,因为它们捕获拓扑信息的能力有…

【Axure高保真原型】3D圆柱图_中继器版

今天和大家分享3D圆柱图_中继器版的原型模板&#xff0c;图表在中继器表格里填写具体的数据&#xff0c;调整坐标系后&#xff0c;就可以根据表格数据自动生成对应高度的圆柱图&#xff0c;鼠标移入时&#xff0c;可以查看对应圆柱体的数据……具体效果可以打开下方原型地址体验…

Springboot+vue的在线试题题库管理系统(有报告),Javaee项目,springboot vue前后端分离项目。

演示视频&#xff1a; Springbootvue的在线试题题库管理系统&#xff08;有报告&#xff09;&#xff0c;Javaee项目&#xff0c;springboot vue前后端分离项目。 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的在线试题题库管理系统&#xff0c;采用M&…

javaSwing销售管理

​ 目录 一、选题背景 近几年来&#xff0c;传统商业与电商似乎是水火不容&#xff0c;大有不是你死便是我活的劲头。一直以来舆论都是一边倒的电商将迅速取代传统零售的论调&#xff0c;然而几年过去&#xff0c;电商的发展确实值得侧目&#xff0c;但传统商业虽然受到不小的…

LeetCode 每日一题 2023/9/25-2023/10/1

记录了初步解题思路 以及本地实现代码&#xff1b;并不一定为最优 也希望大家能一起探讨 一起进步 目录 9/25 460. LFU 缓存9/26 2582. 递枕头9/27 1333. 餐厅过滤器9/28 2251. 花期内花的数目9/29 605. 种花问题9/30 2136. 全部开花的最早一天10/1 9/25 460. LFU 缓存 freqMap…

性能压力测试的定义及步骤是什么

在今天的数字化时代&#xff0c;软件系统的性能和稳定性对于企业的成功至关重要。为了确保软件在高负载和压力情况下的正常运行&#xff0c;性能压力测试成为了不可或缺的环节。本文将介绍性能压力测试的定义、步骤。 一、性能压力测试的定义和目标 性能压力测试是通过模拟实际…

现代c++手撸2309神经网络最简化版230901

用c++输入数据:vector<vector<float>> inputs = { {1, 1}, {1, 0} };数据targets={0,1}; 测试:vector<vector<float>> inputs22 = { {1, 0}, {1,1} }; 构建神经网络,例如:NeuralNetwork nn({ 2, 4, 1 }); 则网络有四层、输入层2个节点、输出层1个节…

网络工程师学习中但是发现这个岗位非常卷怎么办

大家好&#xff0c;我是网络工程师成长日记实验室的郑老师&#xff0c;您现在正在查看的是网络工程师成长日记专栏&#xff0c;记录网络工程师日常生活的点点滴滴 有个同学说&#xff0c;他说现在有很多培训机构搞的这个网络工程师也非常卷。他现在还没有入行&#xff0c;他现在…

【js/es6】合集

目录 随机生成字符串每十个字符换行 随机生成字符串 function generateRandomAlphaNum(len) {var rdmString "";for (; rdmString.length < len; rdmString Math.random().toString(36).substr(2));return rdmString.substr(0, len); }每十个字符换行 string.…