剑指 Offer 09. 用两个栈实现队列
本题目原链接:剑指 Offer 09
目录
剑指 Offer 09题目描述
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
示例1:
输入: ["CQueue","appendTail","deleteHead","deleteHead"] [[],[3],[],[]] 输出:[null,null,3,-1]
示例2:
输入: ["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"] [[],[],[5],[2],[],[]] 输出:[null,-1,null,null,5,2]
提示:
- 1 <= values <= 10000
- 最多会对 appendTail、deleteHead 进行 10000 次调用
思路分析
队列是一个先进先出的数组,从队尾插入,队头弹出。但是相比与栈来说,栈是先进后出,从头部插入,头部弹出。
所以,要想使用两个栈来实现队列,就要解决掉如何正确的实现队列的弹出。这也是为什么需要使用第二个栈的原因。
当使用栈压入的几个数字之后,假设是 1、2、3 这三个数字。那么弹出的时候,按照队列(Queue)的规则应该是先进的先出,也就是 1 先出。可是这恰恰与栈的定义相反,栈是 3 先出。所以我们发现,它们的弹出顺序正好是相反的,这时候只需将 A 栈中的元素反序压入 B 栈中。这时候,B栈中的元素就是 3、2、1, 此时再从 B 栈中弹出,这时候顺序也就正确了。
appendTail思路
命名这两个栈的名字分别为 pushStack 和 deleteStack。appendTail 只需要将元素压入 pushStack 栈中即可。
deleteHead思路
首先需要判断情况。
如果 deleteStack 中已经有元素,那么直接弹出栈顶元素即可。
如果 deleteStack 中没有元素,而 pushStack 存在未反序压入的元素,那么将 pushStack 中的元素反序压入 deleteStack ,然后 deleteStack 弹栈即可。
如果 deleteStack 和 pushStack 都没有元素,只需返回 -1.
实现
#include <stack> class CQueue { public: CQueue() { } void appendTail(int value) { pushStack.push(value); } int deleteHead() { // 默认值,如果两种清空都不满足,返回 -1 int result = -1; // 第二种情况 pushStack 不为空,deleteStack 为空 if (!pushStack.empty() && deleteStack.empty()) { while (!pushStack.empty()) { deleteStack.push(pushStack.top()); pushStack.pop(); } } // 第一种情况 deleteStack 不为空,直接返回 if (!deleteStack.empty()) { result = deleteStack.top(); deleteStack.pop(); } return result; } std::stack<int> pushStack; std::stack<int> deleteStack; }; /** * Your CQueue object will be instantiated and called as such: * CQueue* obj = new CQueue(); * obj->appendTail(value); * int param_2 = obj->deleteHead(); */