题目地址
题目太怪了!!!
简单分析
stack是后进先出,队列是先进先出。
对于一个stack,如果要弹出“队首”元素,需要先将整个stack弹出,才能在最终弹出“队首”。那么需要一个结构来保存被弹出的元素,那么正好第二个stack派上用场。第一个stack弹出的元素,按顺序push进第二个stack,第二个stack按顺序pop就是队列了。对于再加入的元素,先push进第一个stack即可。
下面用()模拟stack,可以清晰的观察整个过程。左边为首,右边为尾。
(1,2,3) - ()
(1,2) (3)
(1)(3,2)
()(3,2,1)
Stack版
class CQueue {
Stack<Integer> s1 = new Stack();
Stack<Integer> s2 = new Stack();
public CQueue() {
}
public void appendTail(int value) {
s1.push(value);
}
public int deleteHead() {
if(s2.isEmpty()){
while(!s1.isEmpty()){
s2.push(s1.pop());
}
}
int r = -1;
if(!s2.isEmpty()){
r = s2.pop();
}
return r;
}
}
执行用时: 44 ms
内存消耗: 46.5 MB
Deque版
class CQueue {
Deque<Integer> s1 = new LinkedList<Integer>();;
Deque<Integer> s2 = new LinkedList<Integer>();;
public CQueue() {
}
public void appendTail(int value) {
s1.push(value);
}
public int deleteHead() {
if(s2.isEmpty()){
while(!s1.isEmpty()){
s2.push(s1.pop());
}
}
int r = -1;
if(!s2.isEmpty()){
r = s2.pop();
}
return r;
}
}
执行用时: 42 ms
内存消耗: 47.2 MB
下面稍微聊聊两者的区别。
java中的stack
- Stack
Stack是Vector的一个子类,它实现了一个标准的后进先出的栈。
单可以index访问。
常见操作如下
s.push();
s.peek();
s.pop()
但他是基于Vector实现的,而Vector是可以按index进行访问的,这导致Stack也是可以的。虽然看起来不是大问题,但违背了单一职责( single responsibility)的设计原理。Java文档中也建议使用Deque来实现。
- Dquen
Deque 是一个接口,是一个双向队列,既可以实现为队列,也可以实现为栈。常用的实现类包括ArrayDeuqe或者LinkedList,栈常用LinkedList,链表中对首尾的访问更快一些。
- 一个例子
Stack<Integer> stack = new Stack<>();
stack.push(1);
stack.push(2);
stack.push(3);
System.out.println(new ArrayList<>(stack)); // prints 1, 2, 3
Deque<Integer> deque = new ArrayDeque<>();
deque.push(1);
deque.push(2);
deque.push(3);
System.out.println(new ArrayList<>(deque)); // prints 3, 2, 1
reference
http://baddotrobot.com/blog/2013/01/10/stack-vs-deque/
https://stackoverflow.com/questions/12524826/why-should-i-use-deque-over-stack
https://www.baifachuan.com/posts/1ed50096.html