【算法训练-队列 一】【结构特性】用两个栈实现队列

简介: 【算法训练-队列 一】【结构特性】用两个栈实现队列

废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【队列的结构特性】,使用【队列】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为:目标公司+最近一年+出现频率排序,由高到低的去牛客TOP101去找,只有两个地方都出现过才做这道题(CodeTop本身汇聚了LeetCode的来源),确保刷的题都是高频要面试考的题。

名曲目标题后,附上题目链接,后期可以依据解题思路反复快速练习,题目按照题干的基本数据结构分类,且每个分类的第一篇必定是对基础数据结构的介绍

用两个栈实现队列【EASY】

还是一道结构特性的题,用两个栈来实现队列

题干

结合队列和栈的结构特性来解题

解题思路

元素进栈以后,只能优先弹出末尾元素,但是队列每次弹出的却是最先进去的元素,如果能够将栈中元素全部取出来,才能访问到最前面的元素,此时,可以用另一个栈来辅助取出

step 1:push操作就正常push到第一个栈栈顶。

step 2:pop操作时,如果第二个栈为空则优先将第一个栈的元素弹出,并依次进入第二个栈中,如果不为空则直接弹出第二个栈栈顶元素

第一个栈中栈底元素也就是最后进入第二个栈的栈顶元素就是队列首部元素

代码实现

给出代码实现基本档案

基本数据结构队列

辅助数据结构

算法

技巧

其中数据结构、算法和技巧分别来自:

  • 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树
  • 10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法
  • 技巧:双指针、滑动窗口、中心扩散

当然包括但不限于以上

import java.util.*;
import java.util.Stack;
public class Solution {
    // 1 定义两个栈, 分别是队列的两头,stackPush为队列尾部,入队使用,stackPop为队列头部,出队使用
    Stack<Integer> stackPush = new Stack<Integer>();
    Stack<Integer> stackPop = new Stack<Integer>();
    public void push(int node) {
    // 2 直接入队
       stackPush.push(node);
    }
    public int pop() {
    // 3 出队前做判断,如果出队栈已经空了,则把入队栈的元素倒着压入出堆栈,如果不为空,则正常从出队栈出
       if(stackPop.isEmpty()){
         while(!stackPush.isEmpty()){
            stackPop.push(stackPush.pop());
         }
       }
       return stackPop.pop();
    }
}

复杂度分析

时间复杂度:时间复杂度是O(N),pop操作可能会触发遍历第一个栈。push操作就是O(1)

空间复杂度:空间复杂度为O(N),按题意本来提供的两个栈,并没有使用辅助数据结构,这里感觉O(1)和O(N)都可以说

拓展知识:队列的基本操作

在Java中,队列(Queue)是一种常用的数据结构,它遵循先进先出(FIFO)的原则。Java提供了多种方式来操作队列,其中最常用的是使用java.util.Queue接口,它是一个基本的队列接口,有许多不同的实现类可供选择,如LinkedListArrayDequePriorityQueue等。以下是一些常见的队列操作:

  1. 创建队列:
Queue<Type> queue = new LinkedList<>(); // 使用LinkedList实现队列
// 或
Queue<Type> queue = new ArrayDeque<>(); // 使用ArrayDeque实现队列
// 或
Queue<Type> queue = new PriorityQueue<>(); // 使用PriorityQueue实现队列
  1. 入队列(添加元素到队列尾部):
queue.add(element); // 或 queue.offer(element);
  1. 出队列(移除队列头部的元素并返回):
Type element = queue.poll(); // 如果队列为空,返回null
// 或
Type element = queue.remove(); // 如果队列为空,抛出异常
  1. 获取队列头部元素但不移除:
Type element = queue.peek(); // 如果队列为空,返回null
// 或
Type element = queue.element(); // 如果队列为空,抛出异常
  1. 检查队列是否为空:
boolean isEmpty = queue.isEmpty();
  1. 获取队列的大小:
int size = queue.size();
  1. 遍历队列:
    可以使用迭代器或增强for循环来遍历队列。
for (Type element : queue) {
    // 处理元素
}

这些是队列的基本操作。不同的队列实现可能具有不同的性能特性和用途,你可以根据你的具体需求选择合适的队列实现。请注意,在多线程环境下使用队列时,需要考虑线程安全性,可以考虑使用java.util.concurrent包中的并发队列实现,如LinkedBlockingQueueConcurrentLinkedQueue

相关文章
|
2月前
|
存储 监控 算法
基于 Go 语言跳表结构的局域网控制桌面软件进程管理算法研究
针对企业局域网控制桌面软件对海量进程实时监控的需求,本文提出基于跳表的高效管理方案。通过多级索引实现O(log n)的查询、插入与删除性能,结合Go语言实现并发安全的跳表结构,显著提升进程状态处理效率,适用于千级进程的毫秒级响应场景。
161 15
|
2月前
|
分布式计算 并行计算 算法
《数据之美》:图结构的精妙世界与算法实践
图是表示多对多关系的非线性数据结构,由顶点和边组成,可建模社交网络、路径导航等复杂系统。核心算法包括BFS/DFS遍历、Dijkstra最短路径、Floyd-Warshall全源最短路径,以及Prim和Kruskal最小生成树算法,广泛应用于推荐系统、社交分析与路径规划。
|
3月前
|
运维 监控 JavaScript
基于 Node.js 图结构的局域网设备拓扑分析算法在局域网内监控软件中的应用研究
本文探讨图结构在局域网监控系统中的应用,通过Node.js实现设备拓扑建模、路径分析与故障定位,提升网络可视化、可追溯性与运维效率,结合模拟实验验证其高效性与准确性。
251 3
|
3月前
|
存储 监控 算法
企业电脑监控系统中基于 Go 语言的跳表结构设备数据索引算法研究
本文介绍基于Go语言的跳表算法在企业电脑监控系统中的应用,通过多层索引结构将数据查询、插入、删除操作优化至O(log n),显著提升海量设备数据管理效率,解决传统链表查询延迟问题,实现高效设备状态定位与异常筛选。
137 3
|
3月前
|
机器学习/深度学习 传感器 算法
基于不变扩展卡尔曼滤波器RI-EKF的同时定位与地图构建SLAM算法的收敛性和一致性特性研究(Matlab代码实现)
基于不变扩展卡尔曼滤波器RI-EKF的同时定位与地图构建SLAM算法的收敛性和一致性特性研究(Matlab代码实现)
123 2
|
6月前
|
算法
基于RMD算法模型的信号传输统计特性的matlab模拟仿真
本项目基于RMD(Random Midpoint Displacement)算法模型,使用MATLAB 2022A进行信号传输统计特性的模拟仿真。通过递归在区间中点加入随机位移,生成具有自相似性和长相关性的随机信号,实现了文中多个仿真图,并提供操作视频与中文注释代码。RMD模型生成的信号均值为零,方差无穷大,具备低误码率、强抗干扰能力及高传输效率等优势,为现代通信系统提供了新思路。
|
存储 算法 Java
解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用
在Java中,Set接口以其独特的“无重复”特性脱颖而出。本文通过解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用。
244 3
|
10月前
|
缓存 监控 算法
内网监控管理软件:PHP 语言队列算法揭秘
在数字化办公环境中,内网监控管理软件对企业的稳定运行和信息安全至关重要。本文深入介绍PHP中的队列算法及其在内网监控软件中的应用,包括监控数据收集、任务调度和日志记录等场景,通过代码示例展示其实现方法。队列算法可提高性能、保证数据顺序并实现异步处理,为企业提供高效的安全保障。
168 1
|
12月前
|
算法
【算法】栈
栈相关算法题,供参考,附有链接地址及板书
137 14
|
存储 缓存 算法
通过优化算法和代码结构来提升易语言程序的执行效率
通过优化算法和代码结构来提升易语言程序的执行效率
307 2