题目来源:LeetCode225:用队列实现栈
问题抽象: 仅使用标准队列操作(先进先出)实现一个栈数据结构(后进先出),需支持栈的全部核心操作,满足以下需求:
-
栈功能定义:
push(x):将元素x压入栈顶;pop():移除并返回栈顶元素;top():返回栈顶元素(不移除);empty():检查栈是否为空。
-
底层约束:
- 仅用队列作为底层容器:可使用多个队列,但操作必须基于队列的标准接口(
入队、出队、查看队首、判空); - 禁止直接使用栈库(如
Stack类)。
- 仅用队列作为底层容器:可使用多个队列,但操作必须基于队列的标准接口(
-
操作要求:
- 所有操作需 正确模拟栈行为(后进先出);
- 时间复杂度要求:
push(x)可为 O(n)(需调整元素顺序);pop()和top()应为 O(1)(理想情况);
- 空间复杂度 O(n)(存储所有元素)。
-
边界处理:
- 空栈调用
pop()或top()时按未定义行为处理(通常抛异常); - 初始栈为空(
empty()返回true)。
- 空栈调用
输入:通过方法调用序列操作栈(如 push(1), pop(), top())
输出:pop() 和 top() 返回栈顶元素;empty() 返回布尔值。
解题思路
使用两个队列 q1 和 q2 实现栈:
- 核心思想:在每次
push操作时,确保新元素始终位于队列前端(即栈顶位置)。 push操作:- 将新元素加入辅助队列
q2。 - 将主队列
q1中的所有元素依次出队并入队到q2(此时q2的前端是新元素,后端是旧元素)。 - 交换
q1和q2的引用(确保q1始终是主队列,q2为空以便复用)。
- 将新元素加入辅助队列
pop操作:直接从q1出队(前端元素即为栈顶)。top操作:返回q1的前端元素(不移除)。empty操作:检查q1是否为空。
时间复杂度分析:push:O(n),需要移动 n 个元素。pop/top/empty:O(1),直接访问队列前端。空间复杂度:O(n),使用两个队列存储元素。
代码实现(Java版)🔥点击下载源码
class MyStack {
private Queue<Integer> q1; // 主队列,存储栈内元素
private Queue<Integer> q2; // 辅助队列,用于调整元素顺序
public MyStack() {
q1 = new LinkedList<>();
q2 = new LinkedList<>();
}
public void push(int x) {
// 1. 新元素加入辅助队列
q2.offer(x);
// 2. 将主队列元素全部移入辅助队列
while (!q1.isEmpty()) {
q2.offer(q1.poll());
}
// 3. 交换主辅队列引用
Queue<Integer> temp = q1;
q1 = q2;
q2 = temp;
}
public int pop() {
// 直接弹出主队列前端元素(栈顶)
return q1.poll();
}
public int top() {
// 返回主队列前端元素(不移除)
return q1.peek();
}
public boolean empty() {
// 检查主队列是否为空
return q1.isEmpty();
}
}
代码说明
- 队列初始化:
q1作为主队列,存储栈内元素。q2作为辅助队列,仅在push操作时暂存数据。
push方法:- 新元素加入
q2。 - 将
q1中所有元素依次移入q2(确保新元素位于队列前端)。 - 交换
q1和q2引用,使q1始终指向主队列。
- 新元素加入
pop方法:直接弹出q1前端元素(即栈顶)。top方法:返回q1前端元素(不删除)。empty方法:检查q1是否为空。
提交详情(执行用时、内存消耗)

1184

被折叠的 条评论
为什么被折叠?



