Implement the following operations of a stack using queues.
push to back
, peek/pop from front
, size
, and is empty
operations are valid.
Update (2015-06-11):
The class name of the Java function had been updated to MyStack instead of Stack.
这题要求很明确, 就是用多个queue来实现stack, 这里用两个queue, pop的时候把queue1中pop出的元素依次push到queue2中, 直到倒数第二个元素, 得到这个元素的值更新当前的topValue供top()调用, 然后最后一个元素pop(), 把queue2赋值给queue1,这样pop的操作是O(n)的, 其他都是O(1),
这里犯了一个极为低级的错误, queue的增加元素的方法为 offer或者add, 这两个方法的不同是 见stackoverflow
when element can not be added to collection the addmethod throws an exception and offer does'nt.
From: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collection.html#add%28E%29
If a collection refuses to add a particular element for any reason other than that it already contains the element, it must throw an exception (rather than returning false). This preserves the invariant that a collection always contains the specified element after this call returns.
From: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Queue.html#offer%28E%29
Inserts the specified element into this queue, if possible. When using queues that may impose insertion restrictions (for example capacity bounds), method offer is generally preferable to method Collection.add(E), which can fail to insert an element only by throwing an exception.
脑补了好几遍code甚至debug都用上了, 最后栽在这种错误上!
class MyStack { private int topValue; private Queue<Integer> queue1; private Queue<Integer> queue2; public MyStack(){ this.topValue = Integer.MIN_VALUE; this.queue1 = new LinkedList<Integer>(); this.queue2 = new LinkedList<Integer>(); } // Push element x onto stack. // O(1) public void push(int x) { // queue1.push(x); //........原来问题在这里。。。queue中要用offer或者add啊!!!! queue1.offer(x); topValue = x; } // Removes the element on top of the stack. // O(n) public void pop() { if(queue1 == null || queue1.size() == 0) { return; } int size = queue1.size(); for(int i = 0; i < size - 1; i++){ if(i == size - 2){ topValue = queue1.peek(); // in the case push(1), push(2), pop, top, when pop is called, queue1.peek() == 2, why is it not 1 ? .... } // queue2.push(queue1.poll()); queue2.offer(queue1.poll()); } queue1.poll(); queue1 = queue2; queue2 = new LinkedList<Integer>(); } // Get the top element. // O(1) public int top() { if(queue1 == null || queue1.size() == 0) { return Integer.MIN_VALUE; } return topValue; } // Return whether the stack is empty. public boolean empty() { return queue1.isEmpty(); } }
优化, 明明用一个Queue就可以了啊。。。何必用两个, 题目说是Queues就非得是多个吗? - -
<span style="color:#333333;">class MyStack { private int topValue; private Queue<Integer> queue; public MyStack(){ this.topValue = Integer.MIN_VALUE; this.queue = new LinkedList<Integer>(); } // Push element x onto stack. // O(1) public void push(int x) { queue.offer(x); topValue = x; } // Removes the element on top of the stack. // O(n) public void pop() { if(queue == null || queue.size() == 0) { return; } int size = queue.size(); for(int i = 0; i < size - 1; i++){ if(i == size - 2){ topValue = queue.peek(); } queue.offer(queue.poll()); } queue.poll(); } // Get the top element. // O(1) public int top() { if(queue == null || queue.size() == 0) { return Integer.MIN_VALUE; } return topValue; } // Return whether the stack is empty. public boolean empty() { return queue.isEmpty(); } } </span>