剑指 Offer 09. 用两个栈实现队列(简单)
Posted 徐同学呀
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指 Offer 09. 用两个栈实现队列(简单)相关的知识,希望对你有一定的参考价值。
题干
剑指 Offer 09. 用两个栈实现队列:
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )。
class CQueue
public CQueue()
public void appendTail(int value)
public int deleteHead()
原题链接:https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/5d3i87/
思路解析
队列:先进先出
栈:先进后出
用两个栈实现 队列,假设有两个栈a、b:
- 添加元素先入栈a
- 删除元素按照队列的特点,是让栈a的最底部的元素出栈
- 但是没办法直接删除栈a最底部的元素,所以将栈中的元素顺序出栈到栈b
- 这样栈a底部的元素就到了栈B的顶部
- 删除栈b顶部元素,就起到了队列先进先出的效果
代码实现
栈 a 用于加入队尾操作,栈 b 用于将元素倒序,从而实现删除队首元素。
加入队尾 appendTail() : 将数字 val 加入栈 a 即可。
删除队首deleteHead() : 有以下三种情况:
- 当栈 b 不为空: b中仍有已完成倒序的元素,因此直接返回 b 的栈顶元素。
- 否则,当 a 为空: 即两个栈都为空,无元素,因此返回 -1 。
- 否则: 将栈 a元素全部转移至栈 b 中,实现元素倒序,并栈 b 的栈顶元素出栈。
用 LinkedList 模拟栈的逻辑,addLast入栈,removeLast出栈。
public class CQueue
LinkedList<Integer> a, b;
public CQueue()
a = new LinkedList<Integer>();
b = new LinkedList<Integer>();
public void appendTail(int value)
a.addLast(value);
public int deleteHead()
// 判断b中还有元素,出栈,先把b中的元素删完
if (!b.isEmpty())
return b.removeLast();
// 如果a为空,那就直接返回-1
if (a.isEmpty())
return -1;
// b为空,且a不为空,
// 则先将a中的所有元素出栈到b中,让顺序颠倒
while (!a.isEmpty())
b.addLast(a.removeLast());
// b栈顶元素出栈
return b.removeLast();
public static void main(String[] args)
CQueue queue = new CQueue();
queue.appendTail(1);
queue.appendTail(2);
queue.appendTail(3);
queue.appendTail(4);
System.out.println(queue.deleteHead());
System.out.println(queue.deleteHead());
System.out.println(queue.deleteHead());
System.out.println(queue.deleteHead());
复杂度分析
时间复杂度:对于插入和删除操作,时间复杂度均为 O(1)。插入不多说,对于删除操作,虽然看起来是 O(n) 的时间复杂度,但是仔细考虑下每个元素只会「至多被插入和弹出 栈2 一次」,因此均摊下来每个元素被删除的时间复杂度仍为 O(1)。
空间复杂度:O(n)。需要使用两个栈存储已有的元素。
特别鸣谢:https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/px2ds5/ 带我走上刷题之路!
以上是关于剑指 Offer 09. 用两个栈实现队列(简单)的主要内容,如果未能解决你的问题,请参考以下文章