Leetcode 刷题日记
2021.2.6(补充)
题目链接:
https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/solution/mian-shi-ti-09-yong-liang-ge-zhan-shi-xian-dui-l-3/
问题描述:
用两个栈实现队列
解答1:
用Stack实现
代码:
import java.util.Stack;
class CQueue {
Stack<Integer> appendStack = new Stack<>();
Stack<Integer> deleteStack = new Stack<>();
public CQueue() {
}
public void appendTail(int value) {
if(appendStack.isEmpty() && !deleteStack.isEmpty()) {
pour(deleteStack,appendStack);
appendStack.push(value);
}else if(deleteStack.isEmpty()){
appendStack.push(value);
}
}
public int deleteHead() {
if(!appendStack.isEmpty() && deleteStack.isEmpty()){
pour(appendStack,deleteStack);
return deleteStack.pop();
}else if(appendStack.isEmpty() && !deleteStack.isEmpty()) return deleteStack.pop();
return -1;
}
private static void pour(Stack from,Stack to){
while(!from.isEmpty()){
to.push(from.pop());
}
}
}
分析:
时间复杂度:O(n)
空间复杂度:O(n)
运行结果:
评注:
可以把队列和栈分别类比为正号和负号,正如两个负号之后得到的是正数,使用两个栈,也能实现队列。这里笔者对代码进行了简单的优化,如果连续执行同样的操作(入队或出队),元素不必在两个栈之间反复倾倒。结合前几道题目,我们不难发现,栈有两大比较重要的功能,一是倒序功能(把栈中元素倾倒出去后,元素反序),二是有序存取功能(若元素按升序存入,则一定被逆序取出),后者可以视为前者的特殊应用,但有时在解决有关问题时难以想到这一点,具体题目可参考上一篇日记https://blog.csdn.net/m0_51404298/article/details/113731106
解答2:
用LinkedList实现
代码:
import java.util.LinkedList;
import java.util.Stack;
class CQueue {
LinkedList<Integer> appendStack = new LinkedList<>();
LinkedList<Integer> deleteStack = new LinkedList<>();
public CQueue() {
}
public void appendTail(int value) {
if(appendStack.isEmpty() && !deleteStack.isEmpty()) {
pour(deleteStack,appendStack);
appendStack.push(value);
}else if(deleteStack.isEmpty()){
appendStack.push(value);
}
}
public int deleteHead() {
if(!appendStack.isEmpty() && deleteStack.isEmpty()){
pour(appendStack,deleteStack);
return deleteStack.pop();
}else if(appendStack.isEmpty() && !deleteStack.isEmpty()) return deleteStack.pop();
return -1;
}
private static void pour(LinkedList from,LinkedList to){
while(!from.isEmpty()){
to.push(from.pop());
}
}
}
分析:
时间复杂度:O(n)
空间复杂度:O(n)
运行结果:
评注:
在Java中,Stack是通过维护一个Vector来实现的,而Vector的底层是一个数组,这就导致其改变容量和增删元素时会产生较大的时间开销。考虑到这一点,解法二改为通过维护两个LinkedList来实现队列。
查阅API文档可知,LinkedList完全能实现Stack的功能,其本身就有pop()和push()两个方法,所以在以后的编程实践中,为了实现更优性能,完全可以用它代替Stack。
运行结果说明,链式实现优于数组实现;而Stack之所以没有采用链式实现,笔者认为是因为LinkedList产生晚于Stack(Stack实现于java1.0,LinkedList实现于java1.2)。