用栈实现队列
将一个栈的元素全部pop,push到另外一个栈
入队
入队直接将元素存入 Stack S1中即可。
不过为了方便实现Peek(),我们引入了一个参数front,将s1中最下面的元素定为s1.
public void push(int x) {
if (s1.isEmpty())
top=x;
s1.add(x);
}
出队与查看队首
第一次出队时候,将s1中的所有元素全部pop push到s2中即可完成倒序。但是之后如果s2中还有元素,则只需要s2.pop()。
如果此时再进行入队,则直接入到s1即可。
当s2整个为空,则再次进行倒序。
public int pop() {
if (s2.isEmpty()) {
while (!s1.isEmpty())
s2.push(s1.pop());
}
return s2.pop();
}
因此 查看队首就变得很简单了
public int peek() {
if (!s2.empty())
return s2.peek();
return front;
}
时间复杂度分析
分析取自LeetCode官方题解!
入队为O(1),不需要解释。
出队均摊为O(1):
总时间复杂度为:n(所有的入队操作产生) + 2 * n(第一次出队操作产生) + n - 1(剩下的出队操作产生), 所以实际时间复杂度为 O(2∗n)。于是我们可以得到每次操作的平均时间复杂度为 O(2n/2n))=O(1)
作者:LeetCode
链接:https://leetcode-cn.com/problems/two-sum/solution/yong-zhan-shi-xian-dui-lie-by-leetcode/
来源:力扣(LeetCode)
用队列实现栈
双队列
入栈
入栈操作很简单,同时我们也定义了一个top便于实现peek
public void push(int x) {
q1.add(x);
top=x;
}
出栈与查看栈顶
出栈操作即将一个队列中,除了最后一个元素以外,全部转到另外一个队列。
不过此时记得维护 TOP
当然,转移后记得将队列返回,为了减少时间复杂度,我们将两个队列互换引用即可。
public int pop() {
while (q1.size()>1){
top=q1.remove();
q2.add(top);
}
int temp=q1.remove();
Queue<Integer> temp1=new LinkedList<>();
q1=temp1;
q1=q2;
q2=temp1;
return temp;
}
-------------------------------------------------------------------
public int top() {
return top;
}
用单队列,实现栈
利用队列可以循环的特性
入栈
每次入队将除了队列中其他元素从头出,从尾再进一次,完成倒序。
public void push(int x) {
q1.add(x);
int size = q1.size();
while (size > 1) {
q1.add(q1.remove());
size--;
}
}
出栈和查看队首
有了入栈的倒序,出栈就很简单了
public void pop() {
q1.remove();
}
public int top() {
return q1.peek();
}