栈与队列Part1
一、232.用栈实现队列
1. 思路分析
由图可以分析得知,第一个栈的元素出栈顺序与队列出顺序相反。
则利用第二个栈,可以通过将In栈元素依次加入Out栈,使得出栈顺序反转。
其实也是利用了栈本身能把输入顺序反转过来的属性。
2. 解法分析
有几点需要注意:
- 必须等Out中元素为空时,再从In中取元素。不然会造成顺序混乱。
- 每次元素从In到Out时,一定要清空In栈。否则也会导致乱序。
- Java要跳空栈异常你就让它跳呗,反正能用try-catch。
时间复杂度:
push和empty为 O ( 1 ) O(1) O(1), pop和peek为 O ( n ) O(n) O(n)
空间复杂度:
O ( n ) O(n) O(n)
Stack操作:pop(), push(), peek(), empty(), size().
3. 代码展示
import java.util.Stack;
class MyQueue {
Stack<Integer> StackIn;
Stack<Integer> StackOut;
public MyQueue() {
StackIn = new Stack<Integer>();
StackOut = new Stack<Integer>();
}
public void push(int x) {
StackIn.push(x); // 自动装箱
}
public int pop() {
if (StackOut.empty()) {
while (!StackIn.empty()) {
StackOut.push(StackIn.pop());
}
}
return StackOut.pop();
}
public int peek() {
if (StackOut.empty()) {
while (!StackIn.empty()) {
StackOut.push(StackIn.pop());
}
}
return StackOut.peek();
}
public boolean empty() {
if (StackIn.empty() && StackOut.empty()) {
return true;
}
return false;
}
}
/**
* 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. 用队列实现栈(一个队列)
1. 思路分析
(使用一个队列实现)
队列与栈不同,来来去去的,队列不会改变元素顺序。
既然队尾的元素就是要出栈的元素,那么就把队尾的元素抬到队头进行操作。
2. 解法分析
- 加入元素操作是相同的,直接加在队尾即可。
- 删除栈顶元素,也就是队尾元素。只需一直将队列头部的元素(除了最后一个元素) 重新添加到队列尾部,此时再去弹出元素就是栈的栈顶,队列的队尾了。
- 取栈顶操作与删除栈顶类似,只不过需要记录一下,再将其添加到队尾就好了。
操作方法还好,问题出在对Java的数据结构操作不清楚的问题。
Java队列操作:
- 创建队列:Queue《Integer》 q = new LinkedList<>();
- 添加元素:q.add(x);
- 删除队头:q.poll();
- 判空:q.isEmpty();
- 取队头:q.peek();
3. 代码展示
import java.util.Queue;
// 思路就是因为队列元素顺序不会变,只要让弹就一直找到队尾后弹队尾。
// 若是取栈顶那就是取队尾,最后保持原队列不变。
class MyStack {
Queue<Integer> queue;
public MyStack() {
queue = new LinkedList<>();
}
public void push(int x) {
queue.add(x);
}
public int pop() {
// 题目说可以使用size()
for (int i = 0; i < queue.size() - 1; i++) {
queue.add(queue.poll());
}
return queue.poll();
}
public int top() {
for (int i = 0; i < queue.size() - 1; i++) {
queue.add(queue.poll());
}
int result = queue.poll();
queue.add(result);
return result;
}
public boolean empty() {
return queue.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();
*/