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(双端队列)来模拟一个栈,只要是标准的栈操作即可。
示例 1:
输入: ["MyQueue", "push", "push", "peek", "pop", "empty"] [[], [1], [2], [], [], []] 输出: [null, null, null, 1, 1, false] 解释: MyQueue myQueue = new MyQueue(); myQueue.push(1); // queue is: [1] myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue) myQueue.peek(); // return 1 myQueue.pop(); // return 1, queue is [2] myQueue.empty(); // return false提示:
1 <= x <= 9
- 最多调用
100
次push
、pop
、peek
和empty
- 假设所有操作都是有效的 (例如,一个空的队列不会调用
pop
或者peek
操作
思路:
栈为先入后出,而队列为先入先出
那么如果要使用栈来实现队列,就是需要改变出栈的顺序,因此就需要一个额外的栈,将原来的栈的元素再依次放入另外一个栈中,就可以使用栈来实现队列,即先入先出
注意:
在入原栈时出栈也要全部出栈,否则会导致错误出栈
出栈的实现:
如果新栈不为空,直接就从新栈里依次取出元素,如果新栈为空,则将旧栈的依次出栈放入新栈里,取出新栈中的栈顶元素并更新新栈的栈顶元素指针,之后再将新栈中的内容存放到旧栈里,返回保留的新栈栈顶元素,就可以使用两个栈来实现队列的操作
只要反复进行这个过程,就能使用两个栈来实现队列的操作(先入先出)
代码实现:
typedef struct {
//一个是原栈,一个是辅助输出的栈
int stackintop , stackouttop;
int stackin[100],stackout[100];
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue *queue = (MyQueue *)malloc(sizeof(MyQueue));
queue->stackintop = 0;
queue->stackouttop = 0;
return queue;
}
void myQueuePush(MyQueue* obj, int x) {
//x元素入栈,并且栈顶指针增加
obj->stackin[(obj->stackintop)++] = x;
}
int myQueuePop(MyQueue* obj) {
//复制栈顶指针,减少对内存的访问
int stackintop = obj->stackintop;
int stackouttop = obj->stackouttop;
//只要新栈为空,那么就要把所有旧栈里的元素都加入到新栈里
if(stackouttop == 0)
{
while(stackintop > 0) //只要旧栈不为空,那么就将旧栈里的所有元素都放入新栈里
obj->stackout[stackouttop++] = obj->stackin[--stackintop];
}
//获取新栈的第一个元素,更新新栈的栈顶指针
int top = obj->stackout[--stackouttop];
//只要新栈不为空
//把新栈的元素全部吸收放入旧栈
while(stackouttop > 0)
obj->stackin[stackintop++] = obj->stackout[--stackouttop];
//更改栈顶指针
obj->stackintop = stackintop;
obj->stackouttop = stackouttop;
返回之前从新栈里取出的值
return top;
}
int myQueuePeek(MyQueue* obj) {
return obj->stackin[0];
}
bool myQueueEmpty(MyQueue* obj) {
return obj->stackintop==0 && obj->stackouttop==0;
}
void myQueueFree(MyQueue* obj) {
obj->stackintop = 0;
obj->stackouttop = 0;
}
225.用队列来实现栈
题目描述:
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(
push
、top
、pop
和empty
)。实现
MyStack
类:
void push(int x)
将元素 x 压入栈顶。int pop()
移除并返回栈顶元素。int top()
返回栈顶元素。boolean empty()
如果栈是空的,返回true
;否则,返回false
。注意:
- 你只能使用队列的标准操作 —— 也就是
push to back
、peek/pop from front
、size
和is empty
这些操作。- 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
示例:
输入: ["MyStack", "push", "push", "top", "pop", "empty"] [[], [1], [2], [], [], []] 输出: [null, null, null, 2, 2, false] 解释: MyStack myStack = new MyStack(); myStack.push(1); myStack.push(2); myStack.top(); // 返回 2 myStack.pop(); // 返回 2 myStack.empty(); // 返回 False提示:
1 <= x <= 9
- 最多调用
100
次push
、pop
、top
和empty
- 每次调用
pop
和top
都保证栈不为空
解法一:
可以使用两个队列来实现栈的功能,即使用其中一个栈来进行数据的备份
解法二:
可以只使用一个队列来实现,即假如队列有n个元素,则将n-1元素先弹出再重复加入队列,就可以只使用一个队列来实现栈的操作