代码随想录 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,一经查实,立即删除!

相关文章

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…

Kafka收发消息核心参数详解

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

《大师级引导-应对困境的工具与技术》读书笔记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…

【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;但传统商业虽然受到不小的…

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

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

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

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

指定vscode黏贴图片路径(VSCode 1.79 更新)

指定vscode黏贴图片路径(VSCode 1.79 更新) 设置中搜索"markdown.copyFiles.destination" 点击AddItem,配置你的key-value&#xff0c;完成。

快排三种递归及其优化,非递归和三路划分

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 目录 快排简介&#xff1a; 快排的三种递归实现&#xff1a; Hoare&#xff1a; 挖坑&#xff1a; 双指针&#xff1a; 小区间优化&#xff1a; 三数取中优化&#xff1a; 快排非递归实现&#xff1a; 快排的三路划…

基于PSO算法的功率角摆动曲线优化研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【设计模式】五、原型模式

文章目录 概述示例传统的方式的优缺点原型模式原理结构图-uml 类图 原型模式解决克隆羊问题的应用实例Sheep类实现clone()运行原型模式在 Spring 框架中源码分析 深入讨论-浅拷贝和深拷贝浅拷贝的介绍 小结 概述 示例 克隆羊问题 现在有一只羊 tom&#xff0c;姓名为: tom, 年…

V4L2 驱动架构介绍

V4L2 简介 Video for Linux two(Video4Linux2)简称 V4L2&#xff0c;是 V4L 的改进版。V4L2 是 linux操作系统下用于视频和音频数据采集设备的驱动框架&#xff0c;为驱动和应用程序提供了一套统一的接口规范。 在 Linux 下&#xff0c;所有外设都被看成一种特殊的文件&#xf…

freertos简介与移植

freertos是一个可裁剪的小型rtos系统&#xff0c;特点&#xff1a; 支持抢占式&#xff0c;合作式和时间片调度saferos衍生自freertos&#xff0c;更完整提供了一个用于低功耗的tickless模式系统的组件在创建时可以选择动态或者静态的ram&#xff0c;例如任务&#xff0c;消息…

MARS: An Instance-aware, Modular and Realistic Simulator for Autonomous Driving

● MARS: An Instance-aware, Modular and Realistic Simulator for Autonomous Driving&#xff08;基于神经辐射场的自动驾驶仿真器&#xff09; ● https://github.com/OPEN-AIR-SUN/mars ● https://arxiv.org/pdf/2307.15058.pdf ● https://mp.weixin.qq.com/s/6Ion_DZGJ…

【新版】系统架构设计师 - 层次式架构设计理论与实践

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录 架构 - 层次式架构设计理论与实践考点摘要层次式体系结构概述表现层框架设计MVC模式MVP模式MVVM模式使用XML设计表现层表现层中UIP设计思想 中间层架构设计业务逻辑层工作流设计业务逻辑层设计 数据访问层…