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

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

废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇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

相关文章
|
5天前
|
算法
【优选算法专栏】专题十三:队列+宽搜(一)
【优选算法专栏】专题十三:队列+宽搜(一)
30 0
|
5天前
|
存储 算法
数据结构与算法:队列
在上篇文章讲解了栈之后,本篇也对这一章进行收尾,来到队列!
数据结构与算法:队列
|
5天前
|
负载均衡 算法 应用服务中间件
面试题:Nginx有哪些负载均衡算法?Nginx位于七层网络结构中的哪一层?
字节跳动面试题:Nginx有哪些负载均衡算法?Nginx位于七层网络结构中的哪一层?
50 0
|
5天前
|
存储 算法 索引
【算法与数据结构】队列的实现详解
【算法与数据结构】队列的实现详解
160 0
|
5天前
|
存储 监控 NoSQL
Redis处理大量数据主要依赖于其内存存储结构、高效的数据结构和算法,以及一系列的优化策略
【5月更文挑战第15天】Redis处理大量数据依赖内存存储、高效数据结构和优化策略。选择合适的数据结构、利用批量操作减少网络开销、控制批量大小、使用Redis Cluster进行分布式存储、优化内存使用及监控调优是关键。通过这些方法,Redis能有效处理大量数据并保持高性能。
25 0
|
5天前
|
算法 网络协议
【计网·湖科大·思科】实验三 总线型以太网的特性、集线器和交换机的区别、交换机的自学习算法
【计网·湖科大·思科】实验三 总线型以太网的特性、集线器和交换机的区别、交换机的自学习算法
8 1
|
5天前
|
存储 算法
数据结构与算法 栈与队列
数据结构与算法 栈与队列
12 0
数据结构与算法 栈与队列
|
5天前
|
网络协议 算法 数据库
【专栏】OSPF是广泛应用的链路状态路由协议,通过分层网络结构和SPF算法实现高效路由。强烈建议收藏!
【4月更文挑战第28天】OSPF是广泛应用的链路状态路由协议,通过分层网络结构和SPF算法实现高效路由。其关键特性包括区域划分、链路状态数据库、邻居关系和路由更新。工作过程涉及邻居发现、信息交换、数据库构建、路由计算及收敛。理解OSPF对于网络管理和规划具有重要意义。
|
5天前
|
机器学习/深度学习 搜索推荐 算法
实现手机 app 千人千面的特性,背后有哪些机器学习算法
实现手机 app 千人千面的特性,背后有哪些机器学习算法
24 0
|
5天前
|
存储 算法
【算法与数据结构】深入解析二叉树(二)之堆结构实现
【算法与数据结构】深入解析二叉树(二)之堆结构实现