先导知识:
栈:一种特殊的线性表,只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端为栈顶,另一端为栈底。栈中的数据元素遵后进先出LIFO(Last in first out)原则。
Java中栈Stack实现的方法:
Stack() | 构造一个空的栈 |
E push(E e) | 将e入栈,并返回e |
E pop() | 将栈顶的元素出栈并返回 |
E peek() | 获取栈顶元素 |
int size() | 获取栈中有效元素个数 |
boolean empty() | 检测栈是否为空 |
队列: 只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First in First out)
Java中队列Queue实现的方法:
boolean offer(E e) | 入队列 |
E poll() | 出队列 |
peek() | 获取队头元素 |
int size() | 获取队列中有效元素个数 |
boolean isEmpty() | 检测队列是否为空 |
LeetCode 232: 用栈实现队列
题目描述:
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push
、pop
、peek
、empty
):
实现 MyQueue
类:
void push(int x)
将元素 x 推到队列的末尾int pop()
从队列的开头移除并返回元素int peek()
返回队列开头的元素boolean empty()
如果队列为空,返回true
;否则,返回false
说明:
- 你 只能 使用标准的栈操作 —— 也就是只有
push to top
,peek/pop from top
,size
, 和is empty
操作是合法的。 - 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
解题思路:
利用两个栈来实现,一个栈为stackIn,一个栈为stackOut,先将元素按照顺序压入stackIn中,然后依次弹出再压入stackOut中,再依次将元素弹出,这样就能实现一个队列的需求了。
class MyQueue {
private Stack<Integer> stackIn;
private Stack<Integer> stackOut;
public MyQueue() {
stackIn = new Stack();
stackOut = new Stack();
}
public void push(int x) {
stackIn.push(x);
}
public int pop() {
dumpStackIn();
return stackOut.pop();
}
public int peek() {
dumpStackIn();
return stackOut.peek();
}
public boolean empty() {
return stackIn.isEmpty() && stackOut.isEmpty();
}
private void dumpStackIn() {
//如果在stackout中仍然有数据,就不能将stackIn中的数据压入stackout中,否则顺序就会错误
if(!stackOut.isEmpty()) {
return;
}
//将stackin中的数据压入stackout中
while(!stackIn.isEmpty()) {
stackOut.push(stackIn.pop());
}
}
}
LeetCode 225: 用队列实现栈
题目描述:
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push
、top
、pop
和 empty
)。
实现 MyStack
类:
void push(int x)
将元素 x 压入栈顶。int pop()
移除并返回栈顶元素。int top()
返回栈顶元素。boolean empty()
如果栈是空的,返回true
;否则,返回false
。
解题思路:
利用一个队列实现,具体思路是将队列中最后一个元素之前的元素全都弹出,然后再重新压入队列中
class MyStack {
private Queue<Integer> queue;
public MyStack() {
queue = new LinkedList<>();
}
public void push(int x) {
queue.offer(x);
}
public int pop() {
rePosition();
return queue.poll();
}
public int top() {
rePosition();
//将元素弹出在重新放入队列中
int result = queue.poll();
queue.offer(result);
return result;
}
public boolean empty() {
return queue.isEmpty();
}
private void rePosition() {
//获取队列的长度
int size = queue.size();
//将最后一个元素之前的元素弹出,在重新压入队列中
while(size > 1) {
queue.offer(queue.poll());
size--;
}
}
}