算法学习Day10栈和队列part1

发布时间 2023-12-22 20:51:07作者: HQWQF

Day10栈和队列part1

By HQWQF 2023/12/21

笔记


232.用栈实现队列

使用栈实现队列的下列操作:

push(x) -- 将一个元素放入队列的尾部。
pop() -- 从队列首部移除元素。
peek() -- 返回队列首部的元素。
empty() -- 返回队列是否为空。

解法:

一道模拟题,不涉及算法知识。

我们知道,队列是先进先出,进去的顺序就是出来的顺序

而栈是先进后出,进去的顺序和出来的顺序相反。

为了让栈出来的顺序和进去的顺序相同,我们可以让栈In出来的元素再进入一个栈out,这样从栈out出来的顺序就是队列的顺序了。

在push数据的时候,只要数据放进输入栈就好,但在pop的时候,若输出栈如果为空,就把进栈数据全部导入进来(注意是全部导入),再从出栈弹出数据,如果输出栈不为空,则直接从出栈弹出数据就可以了。

pop这样的目的是维护队列的顺序,如果不全部导入,最终就会破坏队列的顺序

// 一次性pop完(无事发生): 
//           |1 2 3 4   输入栈栈顶
//输出栈栈顶           |     
 
//           |          输入栈栈顶
//输出栈栈顶    1 2 3 4|      

// 没有pop完,新加入元素:(错误) 
//           |1 2 3 4   输入栈栈顶
//输出栈栈顶           |     

//           |1 2       输入栈栈顶
//输出栈栈顶        3 4|     

//           |1 2 5     输入栈栈顶
//输出栈栈顶           |    

//           |          输入栈栈顶
//输出栈栈顶      1 2 5|   
 //输出顺序:34125(错误)

代码

class MyQueue {
public:
    stack<int> stIn;
    stack<int> stOut;
    /** Initialize your data structure here. */
    MyQueue() {

    }
    /** Push element x to the back of queue. */
    void push(int x) {
        stIn.push(x);
    }

    /** Removes the element from in front of queue and returns that element. */
    int pop() {
        // 只有当stOut为空的时候,再从stIn里导入数据(导入stIn全部数据)
        if (stOut.empty()) {
            // 从stIn导入数据直到stIn为空
            while(!stIn.empty()) {
                stOut.push(stIn.top());
                stIn.pop();
            }
        }
        int result = stOut.top();
        stOut.pop();
        return result;
    }

    /** Get the front element. */
    int peek() {
        int res = this->pop(); // 直接使用已有的pop函数
        stOut.push(res); // 因为pop函数弹出了元素res,所以再添加回去
        return res;
    }

    /** Returns whether the queue is empty. */
    bool empty() {
        return stIn.empty() && stOut.empty();
    }
};

225. 用队列实现栈

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。

解法

这都什么吊题啊

push时和栈一样。

pop时,将主队列元素逐个pop到备份队列,直到主队列只剩下一个元素,此时pop出去,最后把备份队列的元素到push回主队列。

其实只用一个队列也是可以的,只要在pop时将把主队列元素pop出来再push回去,如此执行size()-1次后。pop出来的元素就是目标元素,也就是之前的队列尾。

代码两个队列

class MyStack {
public:
    queue<int> que1;
    queue<int> que2; // 辅助队列,用来备份
    /** Initialize your data structure here. */
    MyStack() {

    }

    /** Push element x onto stack. */
    void push(int x) {
        que1.push(x);
    }

    /** Removes the element on top of the stack and returns that element. */
    int pop() {
        int size = que1.size();
        size--;
        while (size--) { // 将que1 导入que2,但要留下最后一个元素
            que2.push(que1.front());
            que1.pop();
        }

        int result = que1.front(); // 留下的最后一个元素就是要返回的值
        que1.pop();
        que1 = que2;            // 再将que2赋值给que1
        while (!que2.empty()) { // 清空que2
            que2.pop();
        }
        return result;
    }

    /** Get the top element. */
    int top() {
        return que1.back();
    }

    /** Returns whether the stack is empty. */
    bool empty() {
        return que1.empty();
    }
};