1.知识点
栈:先进后出
队列:先进先出
2.刷题
232.用栈实现队列
LeetCode链接 232. 用栈实现队列 - 力扣(LeetCode)
题目描述
方法1:用两个栈实现
package daimasuixianglu.zhanyuduilie;
import java.util.Stack;
/**
* 用两个栈来实现队列
*
* @Author LeiGe
* @Date 2022/10/1
* @Description todo
*/
public class YongZhanShiXianDuiLie232_1 {
Stack<Integer> stIn;
Stack<Integer> stOut;
/**
* 方法1:用两个栈实现队列(一个栈stIn负责输入数据,一个栈stOut负责输出数据)
* 1.push数据:直接push到stIn栈
* 2.pop数据:先检查stOut栈中是否有数据,
* 如果有数据,直接stOut.pop
* 如果没有数据,将stIn栈中数据全部弹出压入到stOut栈中,直接stOut.pop
* 3.peek数据:和pop同理
*/
public YongZhanShiXianDuiLie232_1() {
stIn = new Stack<>();
stOut = new Stack<>();
}
/**
* Push element x to the back of queue.
*/
public void push(int x) {
stIn.push(x);
}
/**
* Removes the element from in front of queue and returns that element.
*/
public int pop() {
dumpStIn();
return stOut.pop();
}
/**
* Get the front element.
*/
public int peek() {
dumpStIn();
return stOut.peek();
}
/**
* Returns whether the queue is empty.
*/
public boolean empty() {
return stIn.isEmpty() && stOut.isEmpty();
}
/**
* 如果stIn为空,那么将stIn中的元素全部放到stOut中
*/
private void dumpStIn() {
if (stOut.isEmpty()) {
while (!stIn.isEmpty()) {
stOut.push(stIn.pop());
}
}
}
}
时间复杂度:O(1)
空间复杂度:O(1)
225.用队列实现栈
LeetCode链接 225. 用队列实现栈 - 力扣(LeetCode)
题目描述
方法1:用两个队列实现
package daimasuixiangshuati.day10_zhanyuduilie;
import java.util.LinkedList;
import java.util.Queue;
/**
* 两个Queue实现
* 通过两个队列来实现,一个主队列,一个用来备份数据
*
* @Author LeiGe
* @Date 2023/10/28
* @Description todo
*/
public class YongDuiLieShiXianZhan225_3 {
Queue<Integer> queue1;
Queue<Integer> queue2;
/**
* 1.用两个Queue实现
* queue1:和栈中保持一样元素的队列,
* queue2:辅助队列
* 2.push操作:
* 2.1先将数据data push到辅助队列queue2中,
* 2.2再将queue1中的所有数据弹出,进入到queue2中这样最后加入的数据data 就放入到辅助队列queue2的最前端了
* 2.3交换queue1和queue2:保持queue1一直为主队列
* 3.top,peek,empty等其他操作:操作queue1即可
*/
public YongDuiLieShiXianZhan225_3() {
queue1 = new LinkedList<>();
queue2 = new LinkedList<>();
}
/**
* Push element x onto stack.
*/
public void push(int x) {
//先放在辅助队列中
queue2.offer(x);
while (!queue1.isEmpty()) {
//把queue1中的元素加入到辅助队列中--此时最后加入的元素就在最前面了
queue2.offer(queue1.poll());
}
Queue<Integer> queueTemp;
queueTemp = queue1;
queue1 = queue2;
// 最后交换queue1和queue2,将元素都放到queue1中
queue2 = queueTemp;
}
/**
* Removes the element on top of the stack and returns that element.
*/
public Integer pop() {
if (!queue1.isEmpty()) {
// 因为queue1中的元素和栈中的保持一致,所以这个和下面两个的操作只看queue1即可
return queue1.poll();
} else {
return null;
}
}
/**
* Get the top element.
*/
public Integer top() {
if (!queue1.isEmpty()) {
return queue1.peek();
} else {
return null;
}
}
/**
* Returns whether the stack is empty.
*/
public boolean empty() {
return queue1.isEmpty();
}
}
时间复杂度:pop为O(N),其他位O(1)
空间复杂度:O(N)
方法2:用1个队列实现
package daimasuixiangshuati.day10_zhanyuduilie;
import java.util.ArrayDeque;
import java.util.Deque;
/**
* 用1个Queue实现
*
* @Author LeiGe
* @Date 2023/10/28
* @Description todo
*/
public class YongDuiLieShiXianZhan225_4 {
// Deque 接口继承了 Queue 接口 所以 Queue 中的 add、poll、peek等效于 Deque 中的 addLast、pollFirst、peekFirst
Deque<Integer> queue;
/**
* 用1个队列实现:
* 1.push操作:直接将数据data push 到队尾中
* 2.pop操作:
* 2.1将队头的数据出队列,然后从尾巴加入(留下最后一个元素)
* 2.2将此时队头的数据出队列(此时的队头元素就是原来的队尾元素)
* 3.peek操作:就是队尾元素
*/
public YongDuiLieShiXianZhan225_4() {
queue = new ArrayDeque<>();
}
/**
* Push element x onto stack.
*/
public void push(int x) {
queue.addLast(x);
}
/**
* Removes the element on top of the stack and returns that element.
*/
public int pop() {
int size = queue.size();
size--;
// 将队头的数据出队列,然后从尾巴加入(留下最后一个元素)
while (size-- > 0) {
queue.addLast(queue.pollFirst());
}
// 将最后一个元素弹出
return queue.pollFirst();
}
/**
* Get the top element.
*/
public int top() {
return queue.peekLast();
}
/**
* Returns whether the stack is empty.
*/
public boolean empty() {
return queue.isEmpty();
}
}
时间复杂度:pop为O(N),其他位O(1)
空间复杂度:O(N)
3.小结
总的思路:
用两个队列可以实现栈(可以优化为1个队列)
用两个栈可以实现队列