解题视频:
核心:
- 不管是队列实现栈,还是栈实现队列,都是一个容器负责存储所有元素,另一个容器负责在操作进行辅助,实现栈或队列数据存储特征的数据输出;
- 其次,栈与队列的题目,画图模拟是解题的关键助力。
232. 用栈实现队列
思路:用栈实现队列首先明确的是仅仅实现队列的“先进先出”的存储特征就满足题目要求了。其次更精致的进行模拟的话,是在使用栈存储数据之后数据也满足先进入的数据总是位于所有数据的顶端。
这两种模式也可以相应形成不同的代码。仅仅实现存储特征的代码,push操作很简单;但pop与peek操作需要两个容器配合实现“先进先出”或“先进后出”的特点。而数据存储顺序满足栈或队列的要求形成的代码,在push阶段会复杂,在pop与peek操作上很简单。
class MyQueue {
private Stack<Integer> stack_1;
private Stack<Integer> stack_2;
public MyQueue() {
stack_1 = new Stack<>();
stack_2 = new Stack<>();
}
public void push(int x) {
// 设置1号栈存储所有的元素
stack_1.push(x);
}
public int pop() {
elementExchange12();
int x = stack_2.pop();
// 2号栈内的所有元素全部移动到了1号栈
elementExchange21();
return x;
}
public int peek() {
// 1号栈内的所有元素全部移动到了2号栈
elementExchange12();
int x = stack_2.peek();
// 2号栈内的所有元素全部移动到了1号栈
elementExchange21();
return x;
}
public boolean empty() {
if(this.stack_1.isEmpty() == true)
return true;
return false;
}
private void elementExchange12(){
while(this.stack_1.isEmpty() == false){
this.stack_2.push(this.stack_1.pop());
}
}
private void elementExchange21(){
while(this.stack_2.isEmpty() == false){
this.stack_1.push(this.stack_2.pop());
}
}
}
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue obj = new MyQueue();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.peek();
* boolean param_4 = obj.empty();
*/
实现队列的先进先出特点的代码
import java.util.Iterator;
import java.util.Stack;
public class MyQueue {
// 设置栈1用于存储元素
private Stack<Integer> stack_1;
private Stack<Integer> stack_2;
public MyQueue() {
stack_1 = new Stack<>();
stack_2 = new Stack<>();
}
public void push(int x) {
// 第一步,栈1元素全部压入栈2
while(stack_1.isEmpty() == false){
stack_2.push(stack_1.pop());
}
// 第二步,新元素入栈1
stack_1.push(x);
// 第三步,栈2的元素再全部回到栈1
while(stack_2.isEmpty() == false){
stack_1.push(stack_2.pop());
}
// 所形成的栈1中的元素满足队列的先进先出的要求,最早进入的元素在最上面
}
public int pop() {
return stack_1.pop();
}
public int peek() {
return stack_1.peek();
}
public boolean empty() {
return stack_1.isEmpty();
}
}
225. 用队列实现栈
思路:也是和栈模拟队列一样有两种风格的代码。关键都是文章开篇所提到的核心。这类题目画图模拟解决是关键。
class MyStack {
Queue<Integer> queue_1;
Queue<Integer> queue_2;
public MyStack() {
this.queue_1 = new LinkedList<>();
this.queue_2 = new LinkedList<>();
}
public void push(int x) {
if(this.queue_1.isEmpty() == false){
this.queue_1.offer(x);
}else{
this.queue_2.offer(x);
}
}
public int pop() {
return elementConvey("pop");
}
public int top() {
return elementConvey("top");
}
public boolean empty() {
if(queue_1.isEmpty() && queue_2.isEmpty())
return true;
return false;
}
private int elementConvey(String op){
int x = 0;
if(this.queue_1.isEmpty() == false){
while (this.queue_1.isEmpty() == false) {
x = queue_1.poll();
// 不让最后一个元素进入队列2,而是将其弹出,实现pop
if (queue_1.isEmpty() && op.equals("pop"))
return x;
queue_2.offer(x);
}
}
else if(this.queue_2.isEmpty() == false){
while (this.queue_2.isEmpty() == false) {
x = queue_2.poll();
if (queue_2.isEmpty() && op.equals("pop"))
return x;
queue_1.offer(x);
}
}
return x;
}
}
/**
* Your MyStack object will be instantiated and called as such:
* MyStack obj = new MyStack();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.top();
* boolean param_4 = obj.empty();
*/
另一种实现栈先进后出存储特点的代码
import javax.swing.text.html.HTMLDocument;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
public class MyStack {
// 设置队列1存储所有的元素
Queue<Integer> queue_1;
Queue<Integer> queue_2;
public MyStack() {
this.queue_1 = new LinkedList<>();
this.queue_2 = new LinkedList<>();
}
public void push(int x) {
// 三步走
// 第一步,x入队列2
queue_2.offer(x);
// 第二步,队列1的元素全部进入队列2
while(queue_1.isEmpty() == false){
queue_2.offer(queue_1.poll());
}
// 第三步,队列1与队列2的指针交换指向
Queue<Integer> temp = queue_1;
queue_1 = queue_2;
queue_2 = temp;
}
public int pop() {
return queue_1.poll();
}
public int top() {
return queue_1.peek();
}
public boolean empty() {
return queue_1.isEmpty();
}
}