剑指 Offer 09. 用两个栈实现队列

剑指 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 次调用

解法一:

stack1用存数据,stack2用来辅助取数据,取数据时,如果stack1为空,直接返回-1,否则先把所有元素压入到stack2中,弹出并记录stack2栈顶元素,把stack2所有元素再压回到stack1

 1 class CQueue {
 2 
 3     Stack<Integer> stack1;
 4     Stack<Integer> stack2;
 5 
 6     public CQueue() {
 7         stack1 = new Stack<Integer>();
 8         stack2 = new Stack<Integer>();
 9     }
10     
11     public void appendTail(int value) {
12         stack1.push(value);
13     }
14     
15     public int deleteHead() {
16         // 如果stack1为空,直接返回-1
17         if(stack1.isEmpty()){
18             return -1;
19         }else{
20             // 否则先把所有元素压入到stack2中
21             while(!stack1.isEmpty()){
22                 stack2.push(stack1.pop());
23             }
24             // 弹出并记录栈顶元素
25             int top = stack2.pop();
26 
27             // 把stack2所有元素再压回到stack1
28             while(!stack2.isEmpty()){
29                 stack1.push(stack2.pop());
30             }
31             return top;
32         }
33     }
34 }

leetcode运行时间为332ms, 空间为46.7mb, 这个时间太恐怖了

复杂度分析:

时间复杂度:插入元素的复杂度为O(1), 删除元素的复杂度为O(2n)

空间复杂度:两个栈, 所以为O(2n)

解法二:

思路来源:https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/solution/mian-shi-ti-09-yong-liang-ge-zhan-shi-xian-dui-l-3/597550

两个栈,一个用来存,一个用来取,两个栈的元素之和等于当前所有元素。stack2不是取元素的辅助栈,而是专门用来取元素,取元素时,先判断 stack2是否为空,如果为空,把stack1中的所有元素都搬运到stack2,此时stack2的栈顶到栈底的元素排列顺序就是将来取元素的顺序

 1 class CQueue {
 2 
 3     Stack<Integer> stack1;
 4     Stack<Integer> stack2;
 5 
 6     public CQueue() {
 7         stack1 = new Stack<Integer>();
 8         stack2 = new Stack<Integer>();
 9     }
10     
11     public void appendTail(int value) {
12         stack1.push(value);
13     }
14     
15     public int deleteHead() {
16         if(stack2.isEmpty()){
17             while(!stack1.isEmpty()){
18                 stack2.push(stack1.pop());
19             }
20         }
21         if(stack2.isEmpty()){
22             return -1;
23         }else{
24             // 如果不为空,直接返回stack2的栈顶元素
25             return stack2.pop();
26         }
27     }
28 }

leetcode运行时间为55ms, 空间为46.5mb, 这个时间已经好多了

复杂度分析:

时间复杂度:存元素的时间为O(1), 取元素虽然有时需要把stack1 的所有元素都拷贝到 stack2, 但是每个元素只会入栈和出栈 stack2 一次,所以取元素的平均时间也为O(1)

空间复杂度:两个栈,一个用来存,一个用来取,两个栈的元素之和等于当前所有元素,所以空间复杂度为O(n)

 

posted @ 2020-09-28 18:07  Lucky小黄人^_^  阅读(165)  评论(0编辑  收藏  举报