今天有在剑指offer一书中看一些算法题,结果早上看了剑指offer下午在LeetCode中做题时就碰到了相同的题目,而且觉着这个问题的解决对我们还是有很大帮助的,所以有必要跟大家分享一下哈~
通过队列实现栈:
Implement the following operations of a stack using queues.
- push(x) -- Push element x onto stack.
- pop() -- Removes the element on top of the stack.
- top() -- Get the top element.
- empty() -- Return whether the stack is empty.
- You must use only standard operations of a queue -- which means only
push to back
,peek/pop from front
,size
, andis empty
operations are valid. - Depending on your language, queue may not be supported natively. You may simulate a queue by using a list or deque (double-ended queue), as long as you use only standard operations of a queue.
- You may assume that all operations are valid (for example, no pop or top operations will be called on an empty stack).
怎样通过队列实现栈呢,我们可以设计两个队列,一个是数据队列,另一个是辅助队列,模拟栈的先进后出,队列是队尾进队头出,也就是说每次取值要取队列的队尾元素,数据队列出队到辅助队列,留下最后一个元素返回,辅助队列再把元素出队到数据队列。当然我们毕竟号称精通Java语言,因此自然不会忘掉Deque这个双端队列接口啦,通过这个接口的方法定义我们只创建一个队列就能实现栈了。因此我们也就有了下面的两种实现:
Deque实现:
package com.gaoxue.LeetCode;
import java.util.Deque;
import java.util.LinkedList;
public class MyStack2 {
Deque<Integer> queue;
public MyStack2() {
queue = new LinkedList<>();
}
public void push(int x) {
queue.offer(x);
}
public int pop() {
return queue.pollLast();
}
public int top() {
return queue.peekLast();
}
public boolean empty() {
return queue.isEmpty();
}
}
Queue实现:
package com.gaoxue.LeetCode;
import java.util.LinkedList;
import java.util.Queue;
public class MyStack {
Queue<Integer> q = new LinkedList<Integer>();
Queue<Integer> q2 = new LinkedList<Integer>();
public MyStack() {}
public void push(int x) {
q.offer(x);
}
public int pop() {
if(!q.isEmpty()){
while(q.size()>1)
q2.offer(q.poll());
}
int result = q.poll();
while(!q2.isEmpty())
q.offer(q2.poll());
return result;
}
public int top() {
if(!q.isEmpty()){
while(q.size()>1)
q2.offer(q.poll());
}
int result = q.peek();
q2.offer(q.poll());
while(!q2.isEmpty())
q.offer(q2.poll());
return result;
}
public boolean empty() {
return q.isEmpty();
}
public static void main(String[] args) {
MyStack myStack = new MyStack();
MyStack2 myStack2 = new MyStack2();
myStack.push(1);
myStack.push(2);
myStack.push(3);
myStack2.push(1);
myStack2.push(2);
myStack2.push(3);
System.out.println(myStack.pop()+" "+myStack2.pop());
System.out.println(myStack.top()+" "+myStack2.top());
}
}
其实逻辑代码比较少,多为一些方法调用难度不是很大,下面我们来看一下怎样用栈去实现队列呢?
Implement the following operations of a queue using stacks.
- push(x) -- Push element x to the back of queue.
- pop() -- Removes the element from in front of queue.
- peek() -- Get the front element.
- empty() -- Return whether the queue is empty.
- You must use only standard operations of a stack -- which means only
push to top
,peek/pop from top
,size
, andis empty
operations are valid. - Depending on your language, stack may not be supported natively. You may simulate a stack by using a list or deque (double-ended queue), as long as you use only standard operations of a stack.
- You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue).
思路与上面相同,我们可以设计两个栈,一个用来放数据(数据栈),一个用来辅助(辅助栈)。数据添加时,会依次压栈,取数据时肯定会取栈顶元素,但我们想模拟队列的先进先出,所以就得取栈底元素,那么辅助栈就派上用场了,把数据栈的元素依次弹出到辅助栈,但保留最后一个元素,最后数据栈就剩下了最后一个元素,直接把元素返回,这时数据栈已经没有了数据。最后呢,把辅助栈的元素依次压人数据栈,这样则成功取到了栈底元素。下面是我的Java实现:
package com.gaoxue.LeetCode;
import java.util.Stack;
public class MyQueue {
Stack<Integer> s = null;
Stack<Integer> s2 = null;
public MyQueue() {
s = new Stack<Integer>();
s2 = new Stack<Integer>();
}
public void push(int x) {
s.push(x);
}
public int pop() {
if(s2.isEmpty()){
while(!s.isEmpty())
s2.push(s.pop());
}
return s2.pop();
}
public int peek() {
if(s2.isEmpty()){
while(!s.isEmpty())
s2.push(s.pop());
}
return s2.peek();
}
public boolean empty() {
return s.isEmpty()&&s2.isEmpty();
}
public static void main(String[] args) {
MyQueue myQueue = new MyQueue();
myQueue.push(1);
myQueue.push(2);
myQueue.push(3);
System.out.print(myQueue.pop()+" ");
System.out.print(myQueue.peek()+" ");
System.out.print(myQueue.pop());
}
}
其实也很简单吧,栈和队列是数据结构相当重要的一个模块,当你把这两道题搞懂的时候有没有觉着对栈和队列的相关问题明朗了许多呢,没错只要你肯努力,定可以乘风破浪~