方法1:使用两个队列实现栈
新元素始终排队到 q。在 pop() 操作中,如果 q2 为空,则除最后一个元素外的所有元素都将移动到 q2。最后,最后一个元素从 q中取消排队并返回。
时间复杂度:
- 推送操作:O(1),As,在每个推送操作中,新元素被添加到队列的末尾。
- 弹出操作:O(N),As,在每个弹出操作中,除最后一个元素外,所有元素都会从队列(q)中弹出并推送到队列(q2)中。
import java.util.LinkedList;
import java.util.Queue;
public class _225 {
// 请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
private Queue<Integer> q;
public void MyStack() {
q = new LinkedList<>();
}
public void push(int x) {
q.add(x);
}
//将q队列中的前size-1个元素装进另外一个队列
public int pop() {
Queue<Integer> q2 = new LinkedList<>();
while (q.size() >1){
q2.add(q.remove());
}
//删除最后元素并返回
int ret = q.remove();
q= q2;
return ret;
}
public int top() {
int top = pop();
push(top);
return top;
}
public boolean empty() {
return q.isEmpty();
}
}
方法2:
- 使用双端队列(双端队列):
双端队列是一种数据结构,支持在恒定时间内从两端添加和删除元素。要使用 Deque 实现 Stack,我们可以使用 addFirst 和 removeFirst 方法分别实现推送和弹出操作。
import java.util.*;
/* Java Program to implement a stack
using only one queue */
class Stack {
// One queue
Queue<Integer> q1 = new LinkedList<Integer>();
void push(int data, int c)
{
// Push the current element first and
// After every recursion add the front element again
q1.add(data);
// Return if size becomes 0
if (c <= 0)
return;
// Decrement size by 1 in every recursion
c--;
// remove front element from queue and return it
// using q1.remove() and call recursive function
push(q1.remove(), c);
}
void pop()
{
// if no elements are there in q1
if (q1.isEmpty())
return;
q1.remove();
}
int top()
{
if (q1.isEmpty())
return -1;
return q1.peek();
}
int size() { return q1.size(); }
// driver code
public static void main(String[] args)
{
Stack s = new Stack();
s.push(1, s.size()); // Value and current size
s.push(2, s.size());
s.push(3, s.size());
System.out.println("current size: " + s.size());
System.out.println(s.top());
s.pop();
System.out.println(s.top());
s.pop();
System.out.println(s.top());
System.out.println("current size: " + s.size());
}
}
// This code is contributed by Susobhan Akhuli
方法3:采用一个单端队列实现栈
- 这种方法背后的想法是创建一个队列并推送其中的第一个元素。
- 在第一个元素之后,我们推送下一个元素,然后再次推送第一个元素,最后弹出第一个元素。
时间复杂度:
- 推送操作:O(N)
- 弹出操作: O(1)
import java.util.*;
/* Java Program to implement a stack
using only one queue */
class Stack {
// One queue
Queue<Integer> q1 = new LinkedList<Integer>();
void push(int x)
{
// Get previous size of queue
int s = q1.size();
// Push the current element
q1.add(x);
// Pop all the previous elements and put them after
// current element
for (int i = 0; i < s; i++) {
q1.add(q1.remove());
}
}
void pop()
{
// if no elements are there in q1
if (q1.isEmpty())
return;
q1.remove();
}
int top()
{
if (q1.isEmpty())
return -1;
return q1.peek();
}
int size() { return q1.size(); }
// driver code
public static void main(String[] args)
{
Stack s = new Stack();
s.push(1);
s.push(2);
s.push(3);
System.out.println("current size: " + s.size());
System.out.println(s.top());
s.pop();
System.out.println(s.top());
s.pop();
System.out.println(s.top());
System.out.println("current size: " + s.size());
}
}
// This code is contributed by Vishal Singh Shekhawat