文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

队列实现栈的3种方法,全都击败了100%的用户!

2024-12-03 18:31

关注

本文转载自微信公众号「Java中文社群」,作者磊哥。转载本文请联系Java中文社群公众号。   

今天我们要讲的是「用队列实现栈」,它们都属于常见的面试题,而我们今天要用多种方法来实现队列到栈的“转变”。

老规矩,先来回顾一下栈(Stack)和队列(Queue)的特性和常见方法。

栈是后进先出(LIFO)的数据结构,常见方法如下:

 

队列是先进先出(FIFO)的数据结构,常见方法如下:

知道了这些基础内容之后,就来看今天的问题吧。

 

题目描述使用队列实现栈的下列操作:

注意:

LeetCode 225:https://leetcode-cn.com/problems/implement-stack-using-queues/

题目解析

这道题的题目很好理解:只需要将先进先出的队列,转换为后进先出的“栈”就可以了,我们可以从多个方向入手来实现此功能,比如使用两个队列插入并交换的方式,或者是一个队列插入再交换的方式,或双端队列的方式来实现此功能,具体实现方法和代码如下。

实现方法 1:两个队列实现栈

之前我们用两个栈实现了一个队列的文章中,主要使用的是「负负得正」的思想,那么当看到此道题时,首先应该想到的是用两个队列来实现一个栈,但这里的实现思路和用栈实现队列的思路又略有不同,因为队列都是先进先出的,我们可以把它理解为「正数」,那么也就不能用「负负得正」的思想了,我们这里使用两个队列来实现栈,主要的操作思路是先将元素插入一个临时队列中,然后再将另一个队列的所有元素插入到临时队列的尾部,从而实现后进先出功能的,具体的实现步骤如下。

步骤一

添加首个元素,入列到临时队列 queue2:

 

步骤二

因为正式队列中无元素,因此无需将 queue1 中的元素移动到临时队列 queue2 的尾部,直接将临时队列和正式队列互换即可:

 

步骤三

添加第二个元素,先入列到临时队列 queue2:

 

步骤四

再将 queue1 中的元素移动到 queue2 的尾部,如下所示:

 

步骤五

再将 queue1 和 queue2 进行互换:

 

步骤六

执行出队操作:

 

最终效果

从最终的效果图我们可以看出,通过两个队列已经实现了后进先出的特性,也就是完成了从队列到栈的转换,实现代码如下:

  1. import java.util.Queue; 
  2.  
  3. class MyStack { 
  4.  
  5.     Queue<Integer> queue1; 
  6.     Queue<Integer> queue2; 
  7.  
  8.     public MyStack() { 
  9.         queue1 = new LinkedBlockingQueue(); 
  10.         queue2 = new LinkedBlockingQueue(); 
  11.     } 
  12.  
  13.      
  14.     public void push(int x) { 
  15.         // 1.入列临时队列二 
  16.         queue2.offer(x); 
  17.         // 2.将队列一的所有元素移动到队列二 
  18.         while (!queue1.isEmpty()) { 
  19.             queue2.offer(queue1.poll()); 
  20.         } 
  21.         // 3.队列一和队列二互换 
  22.         Queue<Integertemp = queue1; 
  23.         queue1 = queue2; 
  24.         queue2 = temp
  25.     } 
  26.  
  27.      
  28.     public int pop() { 
  29.         return queue1.poll(); 
  30.     } 
  31.  
  32.      
  33.     public int top() { 
  34.         return queue1.peek(); 
  35.     } 
  36.  
  37.      
  38.     public boolean empty() { 
  39.         return queue1.isEmpty(); 
  40.     } 

我们在 LeetCode 中提交以上测试代码,执行结果如下:

 

此方法很稳,竟然击败了 100% 的用户。

实现方法 2:一个队列实现栈

那我们可以不可以用一个队列来实现栈呢?答案是肯定的。

我们只需要执行以下两个步骤就可以实现将队列转换为栈了,具体实现步骤如下:

将元素入列到队尾;

再将除队尾之外的所有元素移除并重写入列。

这样操作之后,最后进入的队尾元素反而变成了队头元素,也就实现了后进先出的功能了,如下图所示。

步骤一

元素 1 入列:

 

步骤二

元素 2 入列:

 

步骤三

将最后一个元素之前的所有元素,也就是元素 1,出列重新入列:

 

步骤四

执行出队操作:

 

最终效果

以上思路的实现代码如下:

  1. import java.util.Queue; 
  2.  
  3. class MyStack { 
  4.     Queue<Integer> queue1; 
  5.  
  6.     public MyStack() { 
  7.         queue1 = new LinkedBlockingQueue(); 
  8.     } 
  9.  
  10.      
  11.     public void push(int x) { 
  12.         // 获取原队列长度(要移动的次数) 
  13.         int count = queue1.size(); 
  14.         // 将元素放入队尾 
  15.         queue1.offer(x); 
  16.         // 将除最后一个元素外,其他的元素重新入队 
  17.         for (int i = 0; i < count; i++) { 
  18.             System.out.println("for"); 
  19.             queue1.offer(queue1.poll()); 
  20.         } 
  21.     } 
  22.  
  23.      
  24.     public int pop() { 
  25.         return queue1.poll(); 
  26.     } 
  27.  
  28.      
  29.     public int top() { 
  30.         return queue1.peek(); 
  31.     } 
  32.  
  33.      
  34.     public boolean empty() { 
  35.         return queue1.isEmpty(); 
  36.     } 
  37. 我们把以上代码在 LeetCode  

我们把以上代码在 LeetCode 中提交,执行结果如下:

 

此方法依旧很稳,也是同样的击败了 100% 的用户,只不过此方法在内存方面有更好的表现。

实现方法 3:双端队列实现栈

如果觉得以上方法比较难的话,最后我们还有一个更简单的实现方法,我们可以使用 Java 中的双端队列 ArrayDeque 来实现将元素可以插入队头或队尾,同样移除也是,那么这样我们就可以从队尾入再从队尾出,从而就实现了栈的功能了。

双端队列结构如下:

 

我们来演示一下用双端队列实现栈的具体步骤。

步骤一

元素 1 入队:

 

步骤二

元素 2 入队(队尾):

 

步骤三

再从队尾出队:

 

最终效果

以上思路的实现代码如下:

  1. import java.util.ArrayDeque; 
  2.  
  3. class MyStack { 
  4.     ArrayDeque<Integer> deque; 
  5.  
  6.     public MyStack() { 
  7.         deque = new ArrayDeque<>(); 
  8.     } 
  9.  
  10.      
  11.     public void push(int x) { 
  12.         deque.offer(x); 
  13.     } 
  14.  
  15.      
  16.     public int pop() { 
  17.         return deque.pollLast(); 
  18.     } 
  19.  
  20.      
  21.     public int top() { 
  22.         return empty() ? -1 : deque.peekLast(); 
  23.     } 
  24.  
  25.      
  26.     public boolean empty() { 
  27.         return deque.isEmpty(); 
  28.     } 

我们把以上代码在 LeetCode 中提交,执行结果如下:

 

 

总结

本文我们用 3 种方法实现了将队列转换为栈,其中最简单的方法是用 Java 中自带的双端队列 ArrayDeque 从队尾入并从队尾出就实现了栈 ,其他两个方法使用的是普通队列,通过入队之后再移动元素到入队元素之后的方法,从而实现了栈的功能。

 

来源: Java中文社群内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯