LeetCode Day10

183 阅读3分钟

232.用栈实现队列

使用栈实现队列的下列操作: push(x) -- 将一个元素放入队列的尾部。 pop() -- 从队列首部移除元素。 peek() -- 返回队列首部的元素。 empty() -- 返回队列是否为空。 示例: MyQueue queue = new MyQueue(); queue.push(1); queue.push(2); queue.peek(); // 返回 1 queue.pop(); // 返回 1 queue.empty(); // 返回 false 说明:

  • 你只能使用标准的栈操作 -- 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
  • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
  • 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。

思路

  1. 使用两个栈: 栈是后入先出(LIFO)的数据结构,而队列是先入先出(FIFO)的数据结构。为了使用栈来模拟队列的行为,我们需要两个栈来协同工作。通过适当地移动元素,我们可以确保第一个进入的元素始终可以被正确地弹出。
  2. 推入操作
  • 当有新元素需要加入队列时,我们直接将其推入一个栈(称为inputStack)。
  1. 弹出和查看操作的关键
  • 当我们需要弹出或查看队列的前端元素时,我们查看另一个栈(称为outputStack)。
  • 如果outputStack为空,这意味着我们之前没有移动过元素或者已经弹出了所有元素。此时,我们将inputStack中的所有元素依次弹出并推入outputStack。这样,inputStack的底部元素(也就是最早进入队列的元素)现在位于outputStack的顶部。
  • 然后,我们可以直接从outputStack弹出或查看顶部元素,这就是队列的前端元素。
  1. 判断队列是否为空
  • 为了确定队列是否为空,我们需要检查两个栈是否都为空。只有当两者都为空时,队列才为空。

这种方法的核心思想是利用两个栈之间的元素转移来确保我们总是能够访问到队列的前端元素。当outputStack为空时,我们通过将inputStack中的元素转移到outputStack来重新填充它,从而确保我们总是能够从outputStack中弹出或查看队列的前端元素。

题解

#include <stack>

class MyQueue {
private:
    std::stack<int> inputStack;
    std::stack<int> outputStack;

    void transfer() {
        while (!inputStack.empty()) {
            outputStack.push(inputStack.top());
            inputStack.pop();
        }
    }

public:
    MyQueue() {

    }
    
    void push(int x) {
        inputStack.push(x);
    }
    
    int pop() {
        if(outputStack.empty()){
            transfer();
        }
        int x = outputStack.top();
        outputStack.pop();
        return x;
    }
    
    int peek() {
        if(outputStack.empty()){
            transfer();
        }
        return outputStack.top();
    }
    
    bool empty() {
        if(outputStack.empty()&&inputStack.empty()){
            return true;
        }
        return false;
    }
};

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue* obj = new MyQueue();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->peek();
 * bool param_4 = obj->empty();
 */

225.用队列实现栈

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

  • push(x) -- 元素 x 入栈
  • pop() -- 移除栈顶元素
  • top() -- 获取栈顶元素
  • empty() -- 返回栈是否为空
  • 注意:
  • 你只能使用队列的基本操作-- 也就是 push to back, peek/pop from front, size, 和 is empty 这些操作是合法的。
  • 你所使用的语言也许不支持队列。 你可以使用 list 或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
  • 你可以假设所有操作都是有效的(例如, 对一个空的栈不会调用 pop 或者 top 操作)。

思路

使一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部,此时再去弹出元素就是栈的顺序了。

题解

#include <queue>

class MyStack {
private:
    queue<int> Queue;

public:
    MyStack() {

    }
    
    void push(int x) {
        Queue.push(x);
        for(int i=0;i<Queue.size()-1;i++){
            Queue.push(Queue.front());
            Queue.pop();
        }
    }
    
    int pop() {
        int te= Queue.front();
        Queue.pop();
        return te;
    }
    
    int top() {
        return Queue.front();
    }
    
    bool empty() {
        return Queue.empty();
    }
};

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack* obj = new MyStack();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->top();
 * bool param_4 = obj->empty();
 */