栈与队列理论基础
232.用栈实现队列
- 标签:栈、队列
- 难度:4.5
用两个栈模拟一个队列,核心步骤在pop(),要判断outStack是否是空的。如果为空,要先把inStack里的所有元素转移到outStack里。
可以借助Java的Stack类实现。
class MyQueue {
Stack<Integer> inStack;
Stack<Integer> outStack;
public MyQueue() {
inStack = new Stack();
outStack = new Stack();
}
public void push(int x) {
inStack.push(x);
}
public int pop() {
transfer();
return outStack.pop();
}
public int peek() {
transfer();
return outStack.peek();
}
public boolean empty() {
return inStack.isEmpty() && outStack.isEmpty();
}
public void transfer(){
if(outStack.isEmpty()){
while(!inStack.isEmpty()){
int temp = inStack.pop();
outStack.push(temp);
}
}
}
}
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue obj = new MyQueue();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.peek();
* boolean param_4 = obj.empty();
*/
225.用队列实现栈
- 标签:栈、队列
- 难度:5.0
和上道题一样,但这道题其实可以用一个队列实现。
这道题尝试用Deque(双端队列)接口做,ArrayDeque实现了Deque接口;但是本题只当作单端的用,也就是只用addLast、pollFirst、peekFirst方法。
方法一:用两个队列实现
只往某一个队列里面存元素,会简化操作。
具体实现是每次都保证把装有元素的队列赋给deque1,deque2可以重新new一个空的。
class MyStack {
// Deque 接口继承了 Queue 接口
// 所以 Queue 中的 add、poll、peek等效于 Deque 中的 addLast、pollFirst、peekFirst
Deque<Integer> que1; // 和栈中保持一样元素的队列
Deque<Integer> que2; // 辅助队列
/** Initialize your data structure here. */
public MyStack() {
que1 = new ArrayDeque<>();
que2 = new ArrayDeque<>();
}
/** Push element x onto stack. */
public void push(int x) {
que1.addLast(x);
}
/** Removes the element on top of the stack and returns that element. */
public int pop() {
int size = que1.size();
size--;
// 将 que1 导入 que2 ,但留下最后一个值
while (size-- > 0) {
que2.addLast(que1.peekFirst());
que1.pollFirst();
}
int res = que1.pollFirst();
// 核心步骤:将 que2 对象的引用赋给了 que1 ,此时 que1,que2 指向同一个队列
que1 = que2;
// 如果直接操作 que2,que1 也会受到影响,所以为 que2 分配一个新的空间
que2 = new ArrayDeque<>();
return res;
}
/** Get the top element. */
public int top() {
return que1.peekLast();
}
/** Returns whether the stack is empty. */
public boolean empty() {
return que1.isEmpty();
}
}
其实我一开始不是这么做的,而是分类讨论,保证对装有元素的队列操作,略显繁琐。
class MyStack {
Deque<Integer> deque1;
Deque<Integer> deque2;
public MyStack() {
deque1 = new ArrayDeque();
deque2 = new ArrayDeque();
}
public void push(int x) {
// 分类讨论,下同
if(deque1.isEmpty()){
deque2.addLast(x);
}else if(deque2.isEmpty()){
deque1.addLast(x);
}
}
public int pop() {
int temp;
if(deque1.isEmpty()){
while(true){
temp = deque2.pollFirst();
if(deque2.isEmpty()){
return temp;
}
deque1.addLast(temp);
}
}else if(deque2.isEmpty()){
while(true){
temp = deque1.pollFirst();
if(deque1.isEmpty()){
return temp;
}
deque2.addLast(temp);
}
}
return 0;
}
public int top() {
int temp;
if(deque1.isEmpty()){
while(true){
temp = deque2.pollFirst();
deque1.addLast(temp);
if(deque2.isEmpty()){
return temp;
}
}
}else if(deque2.isEmpty()){
while(true){
temp = deque1.pollFirst();
deque2.addLast(temp);
if(deque1.isEmpty()){
return temp;
}
}
}
return 0;
}
public boolean empty() {
return deque1.isEmpty() && deque2.isEmpty();
}
}
/**
* Your MyStack object will be instantiated and called as such:
* MyStack obj = new MyStack();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.top();
* boolean param_4 = obj.empty();
*/
方法二:用一个队列实现(重要)
没什么可说的,基本操作。
class MyStack {
Deque<Integer> deque1;
int size;
public MyStack() {
deque1 = new ArrayDeque();
size = 0;
}
public void push(int x) {
deque1.addLast(x);
size++;
}
public int pop() {
for(int i = 0; i < size - 1; i++){
int temp = deque1.pollFirst();
deque1.addLast(temp);
}
size--;
return deque1.pollFirst();
}
public int top() {
// 也可以直接用peekLast
int temp = -1;
for(int i = 0; i < size; i++){
temp = deque1.pollFirst();
deque1.addLast(temp);
}
return temp;
}
public boolean empty() {
return deque1.isEmpty();
}
}