学习一下前置知识:Java数据结构之栈和队列
栈和队列在Java中相关的基本操作和原理都已包含。
232.用栈实现队列
文字讲解:用栈实现队列
视频讲解:栈的基本操作!
题设:请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push
、pop
、peek
、empty
):
实现 MyQueue
类:
-
void push(int x)
将元素 x 推到队列的末尾 -
int pop()
从队列的开头移除并返回元素 -
int peek()
返回队列开头的元素 -
boolean empty()
如果队列为空,返回true
;否则,返回false
难点:栈相关的操作,手撕的细节较多。
思路:设置一个入栈和一个出栈,函数复用。
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() {
dumpStackIn();
return stackOut.pop();
}
public int peek() {
dumpStackIn();
return stackOut.peek();
}
public boolean empty() {
return stackIn.empty() && stackOut.empty();
}
// 如果stackOut为空,那么将stackIn中的元素全部放到stackOut中
private void dumpStackIn() {
if (!stackOut.isEmpty()) return;
while (!stackIn.isEmpty()) {
stackOut.push(stackIn.pop());
}
}
}
易错点:相关方法的记忆,画图更好理解。
复杂度分析:
时间复杂度: push和empty为O(1), pop和peek为O(n)。
空间复杂度: O(n)。
225. 用队列实现栈
文字讲解:用队列实现栈
视频讲解:队列的基本操作!
题设:请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push
、top
、pop
和 empty
)。
实现 MyStack
类:
-
void push(int x)
将元素 x 压入栈顶。 -
int pop()
移除并返回栈顶元素。 -
int top()
返回栈顶元素。 -
boolean empty()
如果栈是空的,返回true
;否则,返回false
。
难点:实际上用一个队列就可以实现栈。
思路:每次取出元素时,将size个元素每个都先弹出再加入队列,最后取出的就是目标元素。
class MyStack {
Queue<Integer> queue;
public MyStack() {
queue = new LinkedList<>();
}
public void push(int x) {
queue.add(x);
}
public int pop() {
rePosition();
return queue.poll();
}
public int top() {
rePosition();
int top = queue.poll();
queue.add(top);
return top;
}
public boolean empty() {
return queue.isEmpty();
}
public void rePosition() {
int size = queue.size();
for (int i = 0; i < size - 1; i++) {
queue.add(queue.poll());
}
}
}
易错点:队列的相关方法。构建时,queue继承于LinkedList。
复杂度分析:
- 时间复杂度: pop为O(n),其他为O(1)。
- 空间复杂度: O(n)。