本文主要讲解用队列实现栈的要点与细节,按照步骤思考更方便理解,同类型用栈实现队列
c++与java代码如下,末尾
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(
push
、top
、pop
和empty
)。实现
MyStack
类:
void push(int x)
将元素 x 压入栈顶。int pop()
移除并返回栈顶元素。int top()
返回栈顶元素。boolean empty()
如果栈是空的,返回true
;否则,返回false
。注意:
- 你只能使用队列的标准操作 —— 也就是
push to back
、peek/pop from front
、size
和is empty
这些操作。
具体要点:
1. 首先让我们复习一下,栈和队列的知识点和特点:
栈 stack:先进后出,类比羽毛球桶(先进去的被压在最下面,最后才能取出来)
栈有以下常用操作:入栈,出栈,查找栈顶元素,获取栈元素个数,判空。
队列Queue:先进先出,类比传送带(先进去的,最先达到,最先被处理)
2. 分析题意,这道题让我们用队列实现一个栈,包含:入栈,出栈,获取栈顶元素,判空
- 首先思考入栈:入栈和入队其实没什么差别,都是直接压入元素,让它进去就好了
void push(int x) {
q.push(x); //q是我们定义的队列,这里使用队列的push方法
n++; //数量+1
}
- 其次思考出栈:根据栈的特点,
我们发现正常弹出时:出栈的元素是最后被压入的元素 ,出队的元素是最先被压入队的元素
队列 -> c,b,a -> 出a
栈 |a,b,c -> 出c
如上面所示,队列先会出a元素,想要出c的话,必须把c前面的都出完,才能轮到c
但是倘若把c前面的a和b都出完,再想出a,b时,已经没有了,所以我们需要保存一下ab
应该怎么保存呢?
解决方法:我们先弹出a,再把a压入队中,这时a就在末尾了
队列: -> c,b,a ->
出a后: -> c,b ->
把a重新压入: -> a,c,b ->
- 然后思考获取栈顶元素
栈 |a,b,c -> 需要获取c
队列 -> c,b,a -> 获取末尾c
我们可以直接使用队列的back方法
int top() {
return q.back();
}
- 判空,我们就去判断队列是否为空即可
c++代码如下:
#include<bits/stdc++.h>
using namespace std;
class MyStack {
public:
queue<int>q;
int n=0;
MyStack() {
}
void push(int x) {
q.push(x);
n++;
}
int pop() {
int size = n;
while (size > 1) {
int f = q.front();
q.pop();
q.push(f);
size--;
}
int res = q.front();
q.pop();
n--;
return res;
}
int top() {
return q.back();
}
bool empty() {
return q.empty();
}
};
java代码如下:
class MyStack {
Queue<Integer> q;
int n;
public MyStack() {
q = new LinkedList<>();
}
public void push(int x) {
q.add(x);
n++;
}
public int pop() {
int size=n;
while(size>1){
q.add(q.poll());
size--;
}
int res=q.peek();
q.poll();
n--;
return res;
}
public int top() {
int size=n;
while(size>1){
q.add(q.poll());
size--;
}
int res=q.peek();
q.add(q.poll());
return res;
}
public boolean empty() {
return q.isEmpty();
}
}