题目链接:232. 用栈实现队列 - 力扣(LeetCode)
没啥好说的,用栈实现队列就是简单的使用两个栈,一个进入一个退出
唯一要注意的点为当退出栈不为空时,应当返回退出栈中的元素,当退出栈为空时再将进入栈的元素弹出到退出栈
class MyQueue {
Stack<Integer> stackIn;
Stack<Integer> stackOut;
public MyQueue() {
stackIn = new Stack<>();
stackOut = new Stack<>();
}
public void push(int x) {
stackIn.push(x);
}
public int pop() {
if(!stackOut.isEmpty()){
return stackOut.pop();
}
else{
while(!stackIn.isEmpty()){
stackOut.push(stackIn.pop());
}
return stackOut.pop();
}
}
public int peek() {
if(!stackOut.isEmpty()){
return stackOut.peek();
}
else{
while(!stackIn.isEmpty()){
stackOut.push(stackIn.pop());
}
return stackOut.peek();
}
}
public boolean empty() {
return stackIn.isEmpty() && stackOut.isEmpty();
}
}
/**
* 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();
*/
题目链接:225. 用队列实现栈 - 力扣(LeetCode)
队列的使用:
使用LinkedList来承载Queue,这是由于LinkedList同时实现了List接口和Deque对口,也就是收它既可以看作一个顺序容器,又可以看作一个队列(Queue),同时又可以看作一个栈(stack),这样看来,linkedList简直就是无敌的,当你需要使用栈或者队列时,可以考虑用LinkedList,一方面是因为Java官方已经声明不建议使用Stack类,更遗憾的是,Java里根本没有一个叫做Queue的类(只是一个接口的名字)。关于栈或队列,现在首选是ArrayDeque,它有着比LinkedList(当作栈或队列使用时)更好的性能。
LinkedList的继承体系
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YQR9Tv9z-1668495082706)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/6593bd67-f1fb-484d-82ed-49cfae21dcdc/Untitled.png)]
Java实现一:使用LinkedList实现
思路为,使用queue1,使得队列中和栈中保持一样元素,使用queue2作为辅助队列。
每当需要在queue1中push一个元素时,我们先将元素保存在queue2中,随后将queue1中的所有元素按序移动到queue2中,最终使queue1 = queue2, queue2清零即可,这时我们就实现了使用两个queue完成了队列的顺序。
这样做在实现其他方法时不需要进行修改,直接按照栈的逻辑书写就好
ac代码如下:
class MyStack {
Queue<Integer> queue1;
Queue<Integer> queue2;
public MyStack() {
queue1 = new LinkedList<>();
queue2 = new LinkedList<>();
}
public void push(int x) {
queue2.offer(x);
while(!queue1.isEmpty()){
queue2.offer(queue1.poll());
}
Queue<Integer> temp;
temp = queue1;
queue1 = queue2;
queue2 = temp;
}
public int pop() {
return queue1.poll();
}
public int top() {
return queue1.peek();
}
public boolean empty() {
return queue1.isEmpty();
}
}
/**
* 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();
*/
Java实现2:使用两个deque来实现
思路为其余不变,当需要弹出一个元素时,先将该队列中的所有元素-1都保存到第二个deque中,令queue1 = queue2 ,返回第一个元素中的剩下的最后一个元素即可。
具体步骤如下图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WFlcF62z-1668495082707)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/108faadf-e4b1-438a-9b0d-ad8b774aca24/Untitled.png)]
class MyStack {
Deque<Integer> queue1;
Deque<Integer> queue2;
public MyStack() {
queue1 = new ArrayDeque<>();
queue2 = new ArrayDeque<>();
}
public void push(int x) {
queue1.addLast(x);
}
public int pop() {
int size = queue1.size();
size--;
while(size-- > 0){
queue2.addLast(queue1.peekFirst());
queue1.pollFirst();
}
int res = queue1.pollFirst();
queue1 = queue2;
queue2 = new ArrayDeque<>();
return res;
}
public int top() {
return queue1.peekLast();
}
public boolean empty() {
return queue1.isEmpty();
}
}
当然此道题我们也可以只使用一个队列实现,具体思路为,当需要加入一个末尾元素时,我们将他前面的元素全部重新加入到最后,这样就完成了通过队列实现栈,其余的代码无需改变。