使用队列实现栈的下列操作:
- push(x) -- 元素 x 入栈
- pop() -- 移除栈顶元素
- top() -- 获取栈顶元素
- empty() -- 返回栈是否为空
package StackAndQueue;
import java.util.LinkedList;
import java.util.Queue;
public class LeetCode225_01 {
private Queue<Integer> q1 = new LinkedList<>();
private Queue<Integer> q2 = new LinkedList<>();
private int topElement;
public void push(int x){
//offer是将元素x添加到q1的末尾,如果队列有空间,则成功添加,
// 如没有空间返回false。此用的是LinkedList作为队列,可以动态扩展大小,则可以添加成功
q1.offer(x);
//将最新添加进队列的元素赋值给变量topElement,模拟栈,因为栈顶的元素也是最后被添加进去的,所以要不断更新栈。
topElement = x;
}
public int pop(){
/*这是一个循环,只要q1中的元素数量大于1,就会一直执行循环体内的代码。
这是因为我们想要保留q1中的最后一个元素(即栈顶元素),并将q1中的其他所有元素移动到q2中。*/
while (q1.size()>1){
//从q1队列头部移除并返回一个元素,并将其赋值给topElement。在循环中,这会重复执行,直到q1中只剩下一个元素。
topElement = q1.poll();
//从q1中取出的元素添加到q2队列的尾部。在循环中,这会将除了栈顶元素外的所有元素都从q1移动到了q2。
q2.offer(topElement);
}
//当循环结束后,q1中只剩下一个元素,即栈顶元素。将其赋值给res变量,这个元素就是我们要返回的pop操作的结果。
int res = q1.poll();
/*将q2的引用赋给了q1。现在q1引用了之前q2所引用的队列,而这个队列现在包含了除了栈顶元素外的所有元素。
将temp的引用赋给了q2。现在q2引用了之前q1所引用的队列,而这个队列现在只包含了一个元素,
即刚刚被pop操作移除的栈顶元素的前一个元素。*/
Queue temp = q1;
q1 = q2;
q2 = temp;
//返回pop操作的结果,即res变量的值,它是之前q1中的最后一个元素,也就是栈顶元素。
return res;
}
public int top(){
return topElement;
}
public boolean empty(){
return q1.isEmpty();
}
//测试代码
public static void main(String[] args) {
LeetCode225_01 stack = new LeetCode225_01();
// 测试 push 操作
System.out.println("Pushing elements to the stack:");
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
// 测试 top 操作
System.out.println("Top element is: " + stack.top()); // 应该输出 4
// 测试 pop 操作
System.out.println("Popping elements from the stack:");
System.out.println("Popped element: " + stack.pop()); // 应该输出 4
System.out.println("Popped element: " + stack.pop()); // 应该输出 3
System.out.println("Popped element: " + stack.pop()); // 应该输出 2
System.out.println("Popped element: " + stack.pop()); // 应该输出 1
// 测试 empty 操作
System.out.println("Is the stack empty? " + stack.empty()); // 应该输出 true
}
}
package StackAndQueue;
import java.util.LinkedList;
import java.util.Queue;
public class LeetCode225_02 {
private Queue<Integer> q1 = new LinkedList<>();
public void push(int x){
q1.offer(x);
}
public int pop(){
//获取队列q当前的元素数量,并将其存储在变量size中。
int size = q1.size();
/*只要队列q中的元素数量大于1,就会一直执行循环体内的代码。
这是因为我们的目标是访问并移除队列的最后一个元素(即栈顶元素),但在访问它之前,
需要把队列中的其他所有元素(除了最后一个)移到队列的末尾。*/
while (size>1){
/*从队列q的头部移除一个元素(使用poll方法),然后立即将这个元素添加到队列的尾部(使用offer方法)。
这样做是为了将队列中的每个元素依次移动到最后,直到只剩下最后一个元素。
在每次循环迭代中,队列的第一个元素都会变成新的队列的最后一个元素。*/
q1.offer(q1.poll());
//每次迭代都会将队列中的一个元素从头部移到尾部,所以队列中“有效”的元素数量减少了1。
size--;
}
//当循环结束时,队列q中只剩下一个元素,也就是原本的栈顶元素。此时,执行return q.poll();来移除并返回这个元素。
return q1.poll();
}
public int top(){
int size = q1.size();
while (size>1){
q1.offer(q1.poll());
size--;
}
/*执行int top = q.poll();来移除队列中的这个元素,并将其存储在变量top中。
然而,因为我们并不想真正地移除栈顶元素,所以在下一行q.offer(top);中,
我们将top元素重新添加回到队列的尾部,这样就保持了队列的状态不变,栈顶元素仍然在队列的末尾。
最后,return top;返回保存在top变量中的元素值,这就是栈顶元素的值。*/
int top = q1.poll();
q1.offer(top);
return top;
}
public boolean empty(){
return q1.isEmpty();
}
//测试代码
public static void main(String[] args) {
LeetCode225_02 stack = new LeetCode225_02();
// 测试 push 操作
System.out.println("Pushing elements to the stack:");
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
// 测试 top 操作
System.out.println("Top element is: " + stack.top()); // 应该输出 4
// 测试 pop 操作
System.out.println("Popping elements from the stack:");
System.out.println("Popped element: " + stack.pop()); // 应该输出 4
System.out.println("Popped element: " + stack.pop()); // 应该输出 3
System.out.println("Popped element: " + stack.pop()); // 应该输出 2
System.out.println("Popped element: " + stack.pop()); // 应该输出 1
// 测试 empty 操作
System.out.println("Is the stack empty? " + stack.empty()); // 应该输出 true
}
}