剑指 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();
 */

类似文章

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注