232. 用栈实现队列 - 力扣(LeetCode)(点击前面链接即可查看题目)
一、题目
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(
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 2 3 4 进队列栈此时为: (底)1 2 3 4(顶) 出队列栈为空
此时想进入5:
队列:1 2 3 4 5 进队列栈此时为: (底)1 2 3 4 5 (顶) 出队列栈为空
此时想出1:
队列:1 2 3 4 5 进队列栈此时为: 空 出队列栈为: (底)5 4 3 2 1 (顶)
再将出队列栈的5 pop出去,就完成了出队列,
值得注意的是,想要出一个值A,要看A在进队列栈,还是出队列栈
A在进队列栈:要先将出队列栈清空,再将进队列栈放入出队列栈.然后一直pop到A
A在出队列栈:直接pop到A
注: 代码84开始为本题解, 84行前位栈实现.
typedef int STDataType;
typedef struct Stack
{
STDataType* _a;
int _top; // 栈顶
int _capacity; // 容量
}Stack;
// 初始化栈
void StackInit(Stack* ps)
{
assert(ps);
ps->_a = NULL;
ps->_capacity = 0;
ps->_top = 0;
}
// 入栈
void StackPush(Stack* ps, STDataType data)
{
assert(ps);
if (ps->_top == ps->_capacity)
{
int newcapacity = ps->_capacity == 0 ? 2 : ps->_capacity * 2;
STDataType* tmp = (STDataType*)realloc(ps->_a, newcapacity * sizeof(STDataType));
if (tmp == NULL)
{
perror("realloc fail");
return;
}
ps->_capacity = newcapacity;
ps->_a = tmp;
}
ps->_a[ps->_top] = data;
ps->_top++;
}
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool IsEmptyStack(Stack* ps)
{
assert(ps);
return ps->_top == 0;
}
// 出栈
void StackPop(Stack* ps)
{
assert(ps);
assert(!IsEmptyStack(ps));
ps->_top--;
}
// 获取栈顶元素
STDataType StackTop(Stack* ps)
{
assert(ps);
assert(!IsEmptyStack(ps));
return ps->_a[ps->_top - 1];
}
// 获取栈底元素
STDataType StackBack(Stack* ps)
{
assert(ps);
assert(!IsEmptyStack(ps));
return ps->_a[0];
}
// 获取栈中有效元素个数
int StackSize(Stack* ps)
{
assert(ps);
return ps->_top;
}
// 销毁栈
void StackDestroy(Stack* ps)
{
assert(ps);
free(ps->_a);
ps->_capacity = 0;
ps->_top = 0;
}
typedef struct
{
Stack spush;
Stack spop;
} MyQueue;
MyQueue* myQueueCreate()
{
MyQueue* obj = ( MyQueue*)malloc(sizeof( MyQueue));
StackInit(&obj->spop);
StackInit(&obj->spush);
return obj;
}
void myQueuePush(MyQueue* obj, int x)
{
StackPush(&obj->spush,x);
}
int myQueuePop(MyQueue* obj)
{
if(IsEmptyStack(&obj->spop))
{
while(!IsEmptyStack(&obj->spush))
{
StackPush(&obj->spop,StackTop(&obj->spush));
StackPop((&obj->spush));
}
}
int ret = StackTop(&obj->spop);
StackPop(&obj->spop);
return ret;
}
int myQueuePeek(MyQueue* obj)
{
if(IsEmptyStack(&obj->spop))
{
return StackBack(&obj->spush);
}
else
{
return StackTop(&obj->spop);
}
}
bool myQueueEmpty(MyQueue* obj)
{
return IsEmptyStack(&obj->spop) && IsEmptyStack(&obj->spush);
}
void myQueueFree(MyQueue* obj)
{
StackDestroy(&obj->spop);
StackDestroy(&obj->spush);
free(obj);
}
/**
* Your MyQueue struct will be instantiated and called as such:
* MyQueue* obj = myQueueCreate();
* myQueuePush(obj, x);
* int param_2 = myQueuePop(obj);
* int param_3 = myQueuePeek(obj);
* bool param_4 = myQueueEmpty(obj);
* myQueueFree(obj);
*/