算法训练day9Leetcode232用栈实现队列225用队列实现栈

今天学习的文章和视频链接

https://programmercarl.com/%E6%A0%88%E4%B8%8E%E9%98%9F%E5%88%97%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html

栈与队列理论基础

见我的博客 https://blog.csdn.net/qq_36372352/article/details/135470438?spm=1001.2014.3001.5501

232用栈实现队列

题目描述

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类:

void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
说明:

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

示例 1:

输入:
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]

解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false
 

提示:

1 <= x <= 9
最多调用 100 次 push、pop、peek 和 empty
假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)
 

进阶:

你能否实现每个操作均摊时间复杂度为 O(1) 的队列?换句话说,执行 n 个操作的总时间复杂度为 O(n) ,即使其中一个操作可能花费较长时间。

题目分析

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

最后如何判断队列为空呢?如果进栈和出栈都为空的话,说明模拟的队列为空了。

在代码实现的时候,会发现pop() 和 peek()两个函数功能类似,代码实现上也是类似的,可以思考一下如何把代码抽象一下。

acm模式代码

#include <iostream>
#include <queue>
#include <stack>

class MyQueue {
   
public:
    std::stack<int> stIn;
    std::stack<int> stOut;  
    MyQueue() {
   
        
    }
    
    void push(int x) {
   
        stIn.push(x);
    }
    
    int pop() {
   
        // 只有当stOut为空的时候,再从stIn里导入数据(导入stIn全部数据)
        if (stOut.empty()) {
   
            while (!stIn.empty()) {
   
                stOut.push(stIn.top());
                stIn.pop();
            }
        }
        int result = stOut.top();
        stOut.pop();
        return result;
    }
    
    int peek() {
   
        int res = this->pop();
        stOut.push(res);
        return res;
    }
    
    bool empty() {
   
        return stIn.empty() && stOut.empty();
    }
};

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

int main() {
   
    MyQueue* queue = new MyQueue();
    queue->push(1);
    queue->push(2);
    std::cout << queue->peek() << std::endl;  // 输出 1
    std::cout << queue->pop() << std::endl;   // 输出 1
    std::cout << (queue->empty() ? "true" : "false") << std::endl; // 输出 false

    delete queue; // Don't forget to free the allocated memory

}

peek()的实现,直接复用了pop(), 要不然,对stOut判空的逻辑又要重写一遍。

再多说一些代码开发上的习惯问题,在工业级别代码开发中,最忌讳的就是 实现一个类似的函数,直接把代码粘过来改一改就完事了。

这样的项目代码会越来越乱,一定要懂得复用,功能相近的函数要抽象出来,不要大量的复制粘贴,很容易出问题!

255 用队列实现栈

题目描述

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

实现 MyStack 类:

void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
 

注意:

你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 这些操作。
你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。

我看完题目后的想法

用两个队列,一个队列存一个数便马上弹出到另一个队列

题目分析

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

acm模式代码

#include <iostream>
#include <queue>

class MyStack {
   
public:
    std::queue<int> qe;
    MyStack() {
   

    }
    
    void push(int x) {
   
        qe.push(x);
    }
    
    int pop() {
   
        int n = qe.size() - 1;
        while (n--) {
   
            qe.push(qe.front());
            qe.pop();
        }
        int res = qe.front();
        qe.pop();
        return res;
    }
    
    int top() {
   
        return qe.back();
    }
    
    bool empty() {
   
        return qe.empty();
    }
};

int main() {
   
    MyStack stack;
    stack.push(1);
    stack.push(2);
    std::cout << stack.pop() << std::endl;   // 输出 2
    std::cout << (stack.empty() ? "true" : "false") << std::endl; // 输出 false
}

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

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-12 00:04:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-12 00:04:01       101 阅读
  3. 在Django里面运行非项目文件

    2024-01-12 00:04:01       82 阅读
  4. Python语言-面向对象

    2024-01-12 00:04:01       91 阅读

热门阅读

  1. reset命令

    2024-01-12 00:04:01       55 阅读
  2. go中for range的坑以及解决方案

    2024-01-12 00:04:01       59 阅读
  3. 【源码阅读】交易池txs_list

    2024-01-12 00:04:01       39 阅读
  4. STL之map

    STL之map

    2024-01-12 00:04:01      44 阅读
  5. MySQL 8.0中新增的功能(十)

    2024-01-12 00:04:01       43 阅读
  6. 前端 PM(Project Manager) 分享

    2024-01-12 00:04:01       43 阅读
  7. 【Linux】linux踢出远程登录用户命令

    2024-01-12 00:04:01       54 阅读
  8. vue中实现锚点定位功能

    2024-01-12 00:04:01       63 阅读
  9. Vue的v-for指令、事件处理、表单控制

    2024-01-12 00:04:01       49 阅读
  10. 优化Vue首页加载速度的实用方法

    2024-01-12 00:04:01       59 阅读