【算法训练营】队列合集(2) 2073. 买票需要的时间 || 面试题 03.04. 化栈为队 ||

news2024/11/24 4:40:01

📍前言

本篇将学习queue的OJ题,每一题的标题都是超链接哦,我会将queue的基础知识放到最后供你参考~

🕺作者: 主页

我的专栏
C语言从0到1
探秘C++
数据结构从0到1
探秘Linux
菜鸟刷题集

😘欢迎关注:👍点赞🙌收藏✍️留言

🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要,有问题可在评论区提出,感谢阅读!!!

持续更新中~

📍2073. 买票需要的时间

问题描述

n 个人前来排队买票,其中第 0 人站在队伍 最前方 ,第 (n - 1) 人站在队伍 最后方

给你一个下标从 0 开始的整数数组 tickets ,数组长度为 n ,其中第 i 人想要购买的票数为 tickets[i]

每个人买票都需要用掉 恰好 1 秒 。一个人 一次只能买一张票 ,如果需要购买更多票,他必须走到 队尾 重新排队(瞬间 发生,不计时间)。如果一个人没有剩下需要买的票,那他将会 离开 队伍。

返回位于位置 k(下标从 0 开始)的人完成买票需要的时间(以秒为单位)。

解题思路

  1. 初始化一个队列tp,将每个人的下标依次入队。

  2. 遍历队列tp,对于每个人,检查他的票数tickets[i]是否大于0。如果是,则他将花费1秒购买一张票,并将剩余的票数减1。如果他的票数大于0,则将其下标再次入队。

  3. 如果在队列中找到了位置k的人,并且他的票数为0,则购票过程结束,返回已经花费的时间。

  4. 如果队列中没有剩下的人,则购票过程结束,返回已经花费的时间。

代码实现

下面是相应的代码实现:

class Solution {
public:
    int timeRequiredToBuy(vector<int>& tickets, int k) {
        queue<int> tp;
        int ans = 0;
        for (int i = 0; i < tickets.size(); i++) {
            tp.push(i);
        }
        while (!tp.empty()) {
            if (tickets[tp.front()]) {    // 如果队列中的值当作下标在tickets中有值就进入
                ans++;
                tickets[tp.front()]--;  // 将tickets中对应值减1
                if (tickets[tp.front()]) { // 如果tickets中对应值还是大于0则将下标加入队列
                    tp.push(tp.front());
                }
                else if (tp.front() == k) {  如果tickets中对应值等于0而且下标是k的话
                    break;
                }
            }
            tp.pop();   // 将已访问的下标弹出队列
        }
        return ans;
    }
};

总结

该解决方案的时间复杂度为O(n),其中n为购票人数。该解决方案使用队列来模拟购票过程,通过遍历队列来计算购票时间。

📍面试题 03.04. 化栈为队

问题描述

给定一个 MyQueue 类,要求使用两个栈来实现队列的功能,包括 push、pop、peek 和 empty 方法。

解题思路

题目要求使用两个栈来实现队列,其中一个栈用于入队操作,另一个栈用于出队和获取队头元素操作。具体思路如下:

  1. 创建两个栈 st1 和 st2,st1 用于入队操作,st2 用于出队和获取队头元素操作。
  2. 入队操作 push:将元素 x 直接压入 st1 栈中。
  3. 出队操作 pop:当 st2 栈为空时,将 st1 栈中的元素逐个弹出并压入 st2 栈,这样保证了 st2 的栈顶元素是最早入队的元素。然后从 st2 栈中弹出栈顶元素,即为队首元素。
  4. 获取队头元素操作 peek:与出队操作类似,先将 st1 栈中的元素逐个弹出并压入 st2 栈,然后取得 st2 的栈顶元素作为队头元素。
  5. 判断队列是否为空操作 empty:判断 st1 是否为空即可。

代码如下

class MyQueue {
public:
    /** Initialize your data structure here. */
    MyQueue() {

    }

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

    /** Removes the element from in front of queue and returns that element. */
    int pop() {
        while (!st1.empty()) {
            st2.push(st1.top());
            st1.pop();
        }
        int res = st2.top();
        st2.pop();
        while (!st2.empty()) {
            st1.push(st2.top());
            st2.pop();
        }
        return res;
    }

    /** Get the front element. */
    int peek() {
        while (!st1.empty()) {
            st2.push(st1.top());
            st1.pop();
        }
        int res = st2.top();
        while (!st2.empty()) {
            st1.push(st2.top());
            st2.pop();
        }
        return res;
    }

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

private:
    stack<int> st1;
    stack<int> st2;
};

📍1352. 最后 K 个数的乘积

问题描述

请你实现一个「数字乘积类」ProductOfNumbers,要求支持下述两种方法:

  1. add(int num)
    • 将数字 num 添加到当前数字列表的最后面。
  2. getProduct(int k)
    • 返回当前数字列表中,最后 k 个数字的乘积。
    • 你可以假设当前列表中始终 至少 包含 k 个数字。

题目数据保证:任何时候,任一连续数字序列的乘积都在 32-bit 整数范围内,不会溢出。

解题思路

为了实现该数字乘积类 ProductOfNumbers,我们可以使用一个辅助数组 pre 来记录每个位置之前所有数字的乘积。同时,我们还需要一个变量 len 来记录当前数字列表中数字的个数。

在初始化 ProductOfNumbers 类时,我们将 pre[0] 初始化为 1,并将 len 初始化为 0。

对于 add 方法,如果 num 是 0,则将 len 置为 0,表示清空数字列表。否则,我们将 num 添加到数字列表末尾,并更新 pre[len]pre[len-1] * num,即当前数字列表的乘积。

对于 getProduct 方法,我们首先判断数字列表中的数字个数是否小于 k,如果是,则说明无法计算乘积,直接返回 0。否则,我们可以通过 pre[len] / pre[len-k] 计算最后 k 个数字的乘积。

以上就是解题的思路,我们使用辅助数组 pre 来记录累积乘积,通过更新 prelen 可以实现添加数字和计算乘积的功能。

我的代码

class ProductOfNumbers {
public:
    #define N 40010
    int len,pre[N];
    ProductOfNumbers() {
        pre[0]=1;
        len=0;
    }
    
    void add(int num) {
        if (!num) len=0;
        else{
            pre[++len]=num;
            pre[len]*=pre[len-1];
        }
    }
    
    int getProduct(int k) {
        if (len<k) return 0;
        return pre[len]/pre[len-k];
    }
};

📍queue的基础知识

👨‍🚀小明:“这里我们先看一下文档是怎么说的。总结就是下面几点。”

🎈queue的介绍

queue的文档介绍

  1. ✨队列是一种容器适配器,专门用于在FIFO上下文(先进先出)中操作,其中从容器一端插入元素,另一端提取元素。

  2. ✨队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从队尾入队列,从队头出队列。

  3. 底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少支持以下操作:

  • empty:检测队列是否为空
  • size:返回队列中有效元素的个数
  • front:返回队头元素的引用
  • back:返回队尾元素的引用
  • push_back:在队列尾部入队列
  • pop_front:在队列头部出队列
  1. ✨标准容器类deque和list满足了这些要求。默认情况下,如果没有为queue实例化指定容器类,则使用标准容器deque。

在这里插入图片描述

👨‍🚀小明又给小星展示了一张表“它的常用函数有下面这些,每一个都是链接了文档的超链接,想了解更多就点它,后面接口说明有功能介绍”

🎈queue的常用函数

✨函数声明✨接口说明
✨queue()✨构造空的队列
✨empty()✨检测队列是否为空,是返回true,否则返回false
✨size()✨返回队列中有效元素的个数
✨front()✨返回队头元素的引用
✨back()✨返回队尾元素的引用
✨push()✨在队尾将元素val入队列
✨pop()✨将队头元素出队列

🎈queue的使用

👨‍🚀小明:”按照惯例,现在该做题练练手了“

🧚小星又恢复了活力,双手叉腰、鼻孔朝天道:”来吧,小小队列题“

👨‍🚀小明心想可不能打击他的士气,万一不学了就不好了,于是找到了这题:

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

实现 MyStack 类:

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

注意:

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

示例:

输入:
["MyStack", "push", "push", "top", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 2, 2, false]

解释:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False

提示:

  • 1 <= x <= 9
  • 最多调用100pushpoptopempty
  • 每次调用 poptop 都保证栈不为空

接口如下:

class MyStack {
public:
    MyStack() {

    }
    
    void push(int x) {

    }
    
    int pop() {

    }
    
    int top() {

    }
    
    bool empty() {

    }
};

🧚小星脑袋极速运转:”用队列实现栈的功能,队列是先进先出,栈是先进后出,那么就需要两个队列,要把进入的数据倒来倒去,让后面的到前面就好了,其他的功能也是类似,把握好数据的顺序就可以了,这么简单?不愧是我,“

代码如下:

class MyStack {
public:
    MyStack() {

    }
    
    void push(int x) {
        if(q1.empty())
        {
            q1.push(x);
            while(!q2.empty())
            {
                q1.push(q2.front());
                q2.pop();
            }
        }
        else
        {
            q2.push(x);
            while(!q1.empty())
            {
                q2.push(q1.front());
                q1.pop();
            }
        }
    }
    
    int pop() {
        if(q1.empty())
        {
            int res=q2.front();
            q2.pop();
            return res;
        }
        else
        {
            int res=q1.front();
            q1.pop();
            return res;
        }
    }
    
    int top() {
        if(q1.empty())
        {
            int res=q2.front();
            return res;
        }
        else
        {
            int res=q1.front();
            return res;
        }
    }
    
    bool empty() {
        return q1.empty()&&q2.empty();
    }
private:
    queue<int> q1;
    queue<int> q2;
};

过了!!!

👨‍🚀小明:”嗯嗯,孺子可教也,不错,看来有点天赋的“(其实都在我的掌控之中)

🧚小星:”哼哼,不看看我是谁(得意)“

🧚小星:”你尽管讲,那年我双手插兜,不知道什么是对手。“

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/873781.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【LVS-NAT配置】

配置 node1&#xff1a;128&#xff08;客户端&#xff09; node2&#xff1a;135&#xff08;调度器&#xff09; RS&#xff1a; node3&#xff1a;130 node4&#xff1a;132 node2添加网络适配器&#xff08;仅主机模式&#xff09; [rootnode2 ~]# nmtui[rootnode2 ~]#…

棒球在国际上的流行·棒球1号位

棒球在国际上的流行 1. 棒球的起源与历史 棒球的起源源于美国。19世纪中叶&#xff0c;由于美国领土的扩张&#xff0c;当时的美国殖民地的印第安人将棒球类游戏&#xff0c;带到了当时的弗吉尼亚州的奥克兰。后来&#xff0c;棒球运动流传到了加利福尼亚州的圣迭戈。早期的棒…

Pyqt5使QTextEdit或QLabel等框框背景透明

设置&#xff1a;textEdit->setStyleSheet(“background-color: rgb(255, 255, 255, 60);”);

登录验证两种方案:token和cookie以及对比

cookie HTTP无状态&#xff0c;每次请求都要携带cookie&#xff0c;以帮助识别用户身份&#xff1b; 服务端也可以向客户端set-cookie&#xff0c;cookie大小限制为4kb&#xff1b; cookie默认有跨域限制&#xff0c;不跨域共享和传递&#xff0c;例如&#xff1a; 现代浏览…

7.4.tensorRT高级(2)-使用RAII接口模式对代码进行有效封装

目录 前言1. RAII接口模式2. 问答环节总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0c;之前有看过一遍&#xff0c;但是没有做笔记&#xff0c;很多东西也忘了。这次重新撸一遍&#xff0c;顺便记记笔记。 本次课程学习 tensorRT 高级-使用 RAII 接口模式对…

实战:ros机器人运行不稳定,也许是use_sim_time没有设置对

搞机环境&#xff0c;ubuntu 20.04 ros2 版本 foxy ros机器人搞了很久了&#xff0c;但是有一个初学者很容易忽略的参数&#xff1a;use_sim_time&#xff0c;设置不对&#xff0c;会让程序出跑起来有莫名其妙的问题。 use_sim_time &#xff1a;直白翻译&#xff1a; 用_仿…

一文读懂HTML

文章目录 HTML的历史HTML的作用HTML的基本语言 HTML的历史 HTML&#xff08;HyperText Markup Language&#xff09;的历史可以追溯到20世纪90年代早期&#xff0c;它是互联网发展的重要里程碑之一。以下是HTML的历史概述&#xff1a; 早期阶段&#xff08;1980年代末 - 1990年…

如何撰写一份清晰有效的说明文档

如何撰写一份清晰有效的说明文档 文章目录 导语1.明确读者群体&#xff1a;2.明确文档目的&#xff1a;3.提供清晰的结构&#xff1a;4.使用简洁明了的语言&#xff1a;5.提供具体的示例&#xff1a;6.注意文档格式和风格&#xff1a;7.接受反馈并更新文档&#xff1a;结语 导语…

JZ39 数组中出现次数超过一半的数字

目录 一、题目 二、代码 一、题目 数组中出现次数超过一半的数字_牛客题霸_牛客网 二、代码 class Solution { public:/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可** * param numbers int整型vector * return int…

Spring Boot单元测试与Mybatis单表增删改查

目录 1. Spring Boot单元测试 1.1 什么是单元测试? 1.2 单元测试有哪些好处? 1.3 Spring Boot 单元测试使用 单元测试的实现步骤 1. 生成单元测试类 2. 添加单元测试代码 简单的断言说明 2. Mybatis 单表增删改查 2.1 单表查询 2.2 参数占位符 ${} 和 #{} ${} 和 …

LeetCode 周赛上分之旅 #39 结合中心扩展的单调栈贪心问题

⭐️ 本文已收录到 AndroidFamily&#xff0c;技术和职场问题&#xff0c;请关注公众号 [彭旭锐] 和 BaguTree Pro 知识星球提问。 学习数据结构与算法的关键在于掌握问题背后的算法思维框架&#xff0c;你的思考越抽象&#xff0c;它能覆盖的问题域就越广&#xff0c;理解难度…

赴日IT培训 国内的程序员去日本做IT容易吗?

去日本当程序员的两大要素就是技术和日语。所以说容易也容易&#xff0c;如果学历过关&#xff08;统招大专以上&#xff09;&#xff0c;再加上在国内有经验&#xff0c;所以技术方面问题不大。要说难也难&#xff0c;你要克服语言关&#xff0c;去本本工作对日语的要求比较高…

NeuralNLP-NeuralClassifier的使用记录(一),训练预测自己的【英文文本多分类】

NeuralNLP-NeuralClassifier的使用记录&#xff0c;训练预测自己的英文文本多分类 NeuralNLP-NeuralClassifier是腾讯开发的一个多层多分类应用工具&#xff0c;支持的任务包括&#xff0c;文本分类中的二分类、多分类、多标签&#xff0c;以及层次多标签分类。支持的文本编码…

运维工程师常见面试题

1、http常见返回码 2、mysql的同步方式 1&#xff09;异步复制 MySQL默认的复制即是异步的&#xff0c;主库在执行完客户端提交的事务后会立即将结果返给给客户端&#xff0c;并不关心从库是否已经接收并处理&#xff0c;这样就会有一个问题&#xff0c;主如果crash掉了&a…

207、仿真-51单片机脉搏心率与血氧报警Proteus仿真设计(程序+Proteus仿真+配套资料等)

毕设帮助、开题指导、技术解答(有偿)见文未 目录 一、硬件设计 二、设计功能 三、Proteus仿真图 四、程序源码 资料包括&#xff1a; 需要完整的资料可以点击下面的名片加下我&#xff0c;找我要资源压缩包的百度网盘下载地址及提取码。 方案选择 单片机的选择 方案一&a…

Docker部署rabbitmq遇到的问题 Stats in management UI are disabled on this node

1. Stats in management UI are disabled on this node #进入rabbitmq容器 docker exec -it {rabbitmq容器名称或者id} /bin/bash#进入容器后&#xff0c;cd到以下路径 cd /etc/rabbitmq/conf.d/#修改 management_agent.disable_metrics_collector false echo management_age…

ArcGIS Maps SDK for JavaScript系列之二:认识Map和MapView

目录 Map创建一个 Map 对象的示例代码&#xff1a;Map的常用属性Map的常用方法 MapViewMapView的常用属性MapView的常用方法 在 ArcGIS Maps SDK for JavaScript 中&#xff0c;Map 和 MapView 是两个重要的概念&#xff0c;用于创建和展示地图应用程序。 Map Map 表示一个地图…

2023-08-13 LeetCode每日一题(合并两个有序数组)

2023-08-13每日一题 一、题目编号 88. 合并两个有序数组二、题目链接 点击跳转到题目位置 三、题目描述 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 …

Error: EACCES: permission denied, rename ‘/usr/local/lib/node_modules/appium‘

在使用npm uninstall -g appium卸载appium的过程中报错 Error: EACCES: permission denied, rename /usr/local/lib/node_modules/appium -> /usr/local/lib/node_modules/.appium-cfBVovI6 npm ERR! code EACCES npm ERR! syscall rename npm ERR! path /usr/local/lib/n…

gcc/g++ 编译选项详解

gcc/g 编译选项详解 文章目录 gcc/g 编译选项详解编译步骤gcc 与 g 区别gcc 命令的常用选项编译优化选项-O 优化-O1优化-O2-O0-Os-Ofast-Og-Oz-O 选项控制特定的优化 WarningsReference>>>>> 欢迎关注公众号【三戒纪元】 <<<<< 编译步骤 gcc 、…