剑指 Offer 09. 用两个栈实现队列
一、题目:
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
示例 1:
输入:
["CQueue","appendTail","deleteHead","deleteHead"]
[[],[3],[],[]]
输出:[null,null,3,-1]
示例 2:
输入:
["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
[[],[],[5],[2],[],[]]
输出:[null,-1,null,null,5,2]
提示:
1 <= values <= 10000
最多会对 appendTail、deleteHead 进行 10000 次调用
二、分析与代码:
解题思路:
1.CQueue调用构造方法,初始化两个栈,stack1是尾部插入时放节点进去,stack2是头部删除是放节点进去。
2.当尾部插入时,当stack2中没有值时,直接往stack1中push,当有值时,需要将stack2中的元素都放进stack1中,然后直接push要插入的值。
3.当头部删除时,队列的头是在stack1栈的最底部,所以,需要将stack1中的值一个一个pop,并push到stack2中,这样最底部的元素就到stack2的最顶部了,然后再pop栈stack2最顶部的元素,就可以实现删除了。
代码:
class CQueue { private Stack<Integer> stack1; private Stack<Integer> stack2; public CQueue() { this.stack1 = new Stack<Integer>();//尾部添加 this.stack2 = new Stack<Integer>();//头部删除 } public void appendTail(int value) { while(!stack2.isEmpty()){ stack1.push(stack2.pop()); } stack1.push(value); } public int deleteHead() { while(!stack1.isEmpty()){ stack2.push(stack1.pop()); } if(stack2.isEmpty()) return -1; return stack2.pop(); } } /** * * Your CQueue object will be instantiated and called as such: * CQueue obj = new CQueue(); * obj.appendTail(value); * int param_2 = obj.deleteHead(); */
复杂度分析:
两个方法的时间复杂度都是:O(n)
n个元素入栈, 在入栈和出栈过程中, 只需要存储一个临时变量存储空间, 所以空间复杂度是O(1)。并不是说栈有n个元素, 空间复杂度就是O(n), 而是指除了原本的空间外, 算法需要的额外空间。
(通常来说,只要算法不涉及到动态分配的空间以及递归、栈所需的空间,空间复杂度通常为0(1)。)