学完栈和队列的基础知识后,我们可以通过做算法题,来巩固知识,同时检验自己。
在LeetCode上发现了一道有意思的题目:
leetcode225
描述:请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
解题思路:
要用队列实现栈,我们就需要知道它们各自的存储特点。栈是先进后出,队列为先进先出。
于是我们可以使用两个队列,命名为queue1和queue2。每次执行入栈操作时,我们先将新入栈的元素放到queue2中,然后判断queue1是否有元素,如果有就依次添加到queue2。队列只能从尾部添加,于是每次在queue2中前面的元素都是新入栈。
最后将queue1和queue2里的元素交换。queue1里面就全部是queue2的元素,而queue2就变成了空队列。 交换完之后,下次执行入栈就是和前面一样的啦。
图示:
由于每次入栈操作都确保queue1的前端元素为栈顶元素,因此出栈操作和获得栈顶元素操作都可以简单实现。出栈操作只需要移除queue1的前端元素并返回即可,获得栈顶元素操作只需要获得 queue 1的前端元素并返回即可(不移除元素)。
并且因为 queue 1用于存储栈内的元素,判断栈是否为空时,只需要判断 queue1是否为空即可。
代码实现:
class MyStack {
Queue<Integer> queue1;
Queue<Integer> queue2;
public MyStack() {
queue1 = new LinkedList<Integer>();
queue2 = new LinkedList<Integer>();
}
public void push(int x) {
queue2.offer(x);
//如果queue1有元素,就全部添加到queue2中
while (!queue1.isEmpty()) {
queue2.offer(queue1.poll());
}
//交换queue1和queue2
Queue<Integer> temp = queue1;
queue1 = queue2;
queue2 = temp;
}
public int pop() {
return queue1.poll();
}
public int top() {
return queue1.peek();
}
public boolean empty() {
return queue1.isEmpty();
}
}