【每日一题】LeetCode. 剑指Offer 09. 用两个栈实现队列

每日一题,防止痴呆 = =

一、题目大意

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
在这里插入图片描述
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof

二、题目思路以及AC代码

思路:

这道题我一开始看到的时候第一思路是这样的:因为让用两个栈来实现队列,我们只需要一个栈来存储元素,另一个栈在输出时用来颠倒一下就可以了,我觉得这也是最暴力的办法了,然后时间花费的有一些多,我就考虑如何更简便的去做。

上面的做法是每次在输出元素的时候,都要对存储数据的栈做一次颠倒,这着实没有什么必要,因为我们如果先连续的向队列里push,再连续的从队列里取出,其实我们只要颠倒一次,然后不断的从颠倒的栈中取出即可,这样我们可以针对连续push和连续pop的情况进行优化,即我们只在push和pop操作交替的时候,才进行颠倒的操作,这样应该就可以减少很多时间消耗,结果表明,确实效果更好的一些,但还不是很明显。

然后我参考了一下速度快一些的代码的思路,他们和我一样是使用两个数组,一个用来append,一个用来delete,但是在append的时候不做操作,直接append到第一个栈中,然后在输出元素,也就是delete的时候,如果第二个栈不为空,则直接delete,如果为空,那么把第一个栈中的元素颠倒顺序保存到第二个栈中,继续。这种方法看起来好像是包含了上面的优化方法的。

AC代码

最暴力:

class CQueue {
private:
    stack<int> content;
public:
    CQueue() {

    }
    
    void appendTail(int value) {
        content.push(value);
    }
    
    int deleteHead() {
        if (content.empty()) return -1;

        stack<int> temp;
        while (!content.empty()) {
            temp.push(content.top()); content.pop();
        }
        int res = temp.top(); temp.pop();
        while (!temp.empty()) {
            content.push(temp.top()); temp.pop();
        }
        return res;
    }
};

/**
 * Your CQueue object will be instantiated and called as such:
 * CQueue* obj = new CQueue();
 * obj->appendTail(value);
 * int param_2 = obj->deleteHead();
 */

只在操作交替时颠倒:

class CQueue {
private:
    stack<int> append_stack;
    stack<int> delete_stack;
    bool appending;
public:
    CQueue() {
        appending = true;
    }
    
    void appendTail(int value) {
        if (!appending) {
            // while (!append_stack.empty()) append_stack.pop();
            appending = true;
            while(!delete_stack.empty()) {
                append_stack.push(delete_stack.top()); delete_stack.pop();
            }
        }
        append_stack.push(value);
    }
    
    int deleteHead() {
        if (appending) {
            // while (!delete_stack.empty()) delete_stack.pop();
            appending = false;
            while (!append_stack.empty()) {
                delete_stack.push(append_stack.top()); append_stack.pop();
            }
        }
        if (delete_stack.empty()) return -1;
        int res = delete_stack.top(); delete_stack.pop();
        return res;
    }
};

/**
 * Your CQueue object will be instantiated and called as such:
 * CQueue* obj = new CQueue();
 * obj->appendTail(value);
 * int param_2 = obj->deleteHead();
 */

只在需要时颠倒:

class CQueue {
private:
    stack<int> append_stack;
    stack<int> delete_stack;
public:
    CQueue() {
        
    }
    
    void appendTail(int value) {
        append_stack.push(value);
    }
    
    int deleteHead() {
        int res = -1;
        if (!delete_stack.empty()) {
            res = delete_stack.top(); delete_stack.pop();
            return res;
        }
        while (!append_stack.empty()) {
            delete_stack.push(append_stack.top()); append_stack.pop();
        }
        if (!delete_stack.empty()) {
            res = delete_stack.top(); delete_stack.pop();
        }
        return res;
    }
};

/**
 * Your CQueue object will be instantiated and called as such:
 * CQueue* obj = new CQueue();
 * obj->appendTail(value);
 * int param_2 = obj->deleteHead();
 */

如果有问题,欢迎大家指正!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章