方法思路
使用两个栈(stack1和stack2)来实现一个队列。stack1用于入队操作,stack2用于出队操作。当需要出队时,如果stack2为空,则将stack1中的所有元素弹出并压入stack2,这样stack2的栈顶元素就是队列的头部元素。
import java.util.Stack;
public class QueueWithTwoStacks<T> {
private Stack<T> stack1; // 用于入队
private Stack<T> stack2; // 用于出队
public QueueWithTwoStacks() {
stack1 = new Stack<>();
stack2 = new Stack<>();
}
// 入队操作
public void enqueue(T item) {
stack1.push(item);
}
// 出队操作
public T dequeue() {
if (isEmpty()) {
throw new IllegalStateException("Queue is empty");
}
// 如果stack2为空,则将stack1中的所有元素转移到stack2
if (stack2.isEmpty()) {
while (!stack1.isEmpty()) {
stack2.push(stack1.pop());
}
}
return stack2.pop();
}
// 查看队首元素
public T peek() {
if (isEmpty()) {
throw new IllegalStateException("Queue is empty");
}
if (stack2.isEmpty()) {
while (!stack1.isEmpty()) {
stack2.push(stack1.pop());
}
}
return stack2.peek();
}
// 判断队列是否为空
public boolean isEmpty() {
return stack1.isEmpty() && stack2.isEmpty();
}
// 获取队列大小
public int size() {
return stack1.size() + stack2.size();
}
}
成员变量:
stack1:用于入队操作,所有入队的元素都压入此栈。
stack2:用于出队操作,当需要出队时,如果此栈为空,则将stack1中的元素全部弹出并压入stack2。
enqueue(T item):
将元素压入stack1,完成入队操作。
dequeue():
如果队列为空,抛出异常。
如果stack2为空,将stack1中的所有元素弹出并压入stack2,此时stack2的栈顶元素即为队列的头部元素。
弹出并返回stack2的栈顶元素。
peek():
类似于dequeue(),但不移除元素,仅返回队首元素。
isEmpty():
当stack1和stack2都为空时,队列为空。
size():
返回stack1和stack2中元素的总和。
复杂度分析
enqueue(T item):O(1),直接将元素压入stack1。
dequeue():
最好情况:O(1),当stack2不为空时。
最坏情况:O(n),当stack2为空且需要将stack1中的所有元素转移到stack2时。
peek():与dequeue()相同。
isEmpty():O(1)。
size():O(1)。