当前位置: 首页 > news >正文

018数据结构之队列——算法备赛

移掉k位数字

给你一个以字符串表示的非负整数 num 和一个整数 k ,移除这个数中的 k 位数字,使得剩下的数字最小。请你以字符串形式返回这个最小的数字。

注意:输出不能有任何前导零,给定的num不包含前导0。

​ 从原数字移除所有的数字,剩余为空就是 0 。

原题链接

思路分析

判断两个正整数的大小关系,先看位数,位数相同,从左往右看第一个不同的数字,该位数字小的则小,例123467<123589;

题目说移掉k位数字,可以看成选择 t =(s-k)(s为字符串长度)位数字组成的最小数值。

我们可以遍历字符串,每遍历到一位判断是否保留或移除,关键问题是如何决策是否保留

我们将保留的数字尾插在一个双端队列中,队列中的每一个数对应所求的每一位,每次遍历到一位数字,将它与队列尾部的数字比较,较小的话,队列尾删,直到该数字大于队列尾部,入队。这样做可以确保高位数字尽量小同时要保证队列长度符合t

注:选用双端队列作为解题的数据结构而不选用栈的原因:将容器中数据转换为目标字符串时更方便,(栈顶——>栈底)=(低位数字——>高位数字)。

代码

string removeKdigits(string num, int k) {int s1=num.size();int s=s1-k;string tar;if(!s) return "0";deque<char>st;for(int i=0;i<s1;i++){//s-st.size()表示队列剩余空间,s1-i表示字符串剩余长度while(!st.empty()&&num[i]<st.back()&&s-st.size()<s1-i){st.pop_back();}if(st.size()<s)st.push_back(num[i]);}while(!st.empty()){if(!tar.size()&&st.front()=='0'){st.pop_front(); continue;}  //去除前导0tar.push_back(st.front());st.pop_front();}if(!tar.size()) return "0";  //为空置为“0”return tar;
}

删除字符串中所有的相邻重复项

问题描述

给你一个字符串 s,「k 倍重复项删除操作」将会从 s 中选择 k 个相邻且相等的字母,并删除它们,使被删去的字符串的左侧和右侧连在一起。

你需要对 s 重复进行无限次这样的删除操作,直到无法继续为止。

在执行完所有删除操作后,返回最终得到的字符串。

本题答案保证唯一。

原题链接

思路分析

使用栈模拟删除的操作,使用队列返回最终得到的字符串,所以选择双端队列。

代码

string removeDuplicates(string s, int k) {deque<pair<char,int>>dq;for(char ch:s){  if(dq.empty()){dq.push_back({ch,1});}else{auto&[key,val] = dq.back();if(key==ch){val++;if(val==k) dq.pop_back();  //k个重复项删除}else{dq.push_back({ch,1});}}}string ans;while(!dq.empty()){  //从头到尾返回结果字符串auto [key,val] =dq.front();ans+=string(val,key);dq.pop_front();}return ans;
}

知道秘密的人

问题描述

在第 1 天,有一个人发现了一个秘密。

给你一个整数 delay ,表示每个人会在发现秘密后的 delay 天之后,每天 给一个新的人 分享 秘密。同时给你一个整数 forget ,表示每个人在发现秘密 forget 天之后会 忘记 这个秘密。一个人 不能 在忘记秘密那一天及之后的日子里分享秘密。

给你一个整数 n ,请你返回在第 n 天结束时,知道秘密的人数。由于答案可能会很大,请你将结果对 109 + 7 取余 后返回。

  • 2 <= n <= 1000
  • 1 <= delay < forget <= n

原题链接

思路分析

初步设想:可以设计一个双端队列,每天将遗忘秘密的人从头部出队,新发现秘密的人从尾部入队,最后队列中剩余的总人数就是答案。

初步设想其实是维护了两个临界点:遗忘秘密的临界点front和发现秘密的临界点back。这是一个大致的想法,还有一个问题是每个人要发现秘密delay天后才能分享秘密,所以还需维护一个可以分享秘密的临界点valid。为了实现这三个临界点的特殊队列,我们可以用一个数组来自己实现:

在这里插入图片描述

最后[front,back]区间内的总人数就是答案。因为三个指针每次移动的步长是一样的,可以用anssum来动态地维护[front,back][front,valid)内的总人数。

代码

int peopleAwareOfSecret(int n, int delay, int forget) {const int MOD = 1e9+7;int ans = 1,sum = 0;vector<int>q;  //数组模拟队列q.push_back(1);int front=0;  //首尾指针int valid = front;  //[front,valid)范围内的人可分享秘密for(int i=2;i<=n;i++){if(i>delay){sum = (sum+q[valid++])%MOD;  //可分享秘密的人数增加}if(i>forget){ans = (ans-q[front]+MOD)%MOD;  //知道秘密的总人数减少sum = (sum-q[front++]+MOD)%MOD;  //可分享秘密的人减少}q.push_back(sum);  //新增发现秘密的人ans = (ans+sum)%MOD;  //更新答案}return ans;
}
http://www.dtcms.com/a/503015.html

相关文章:

  • 开源 Linux 服务器与中间件(四)服务器--Tomcat
  • Auto CAD二次开发——测试功能
  • 《Linux进阶指令实操指南》:文件查看、时间管理、搜索压缩全覆盖(附高频案例)
  • Socket编程学习记录
  • AI“缝合怪”变“神作”,游戏宣传图工作流
  • Java 大视界 -- Java 大数据机器学习模型在金融衍生品定价中的创新方法与实践
  • PHPMailer下载和使用教程(非常详细)
  • 傻瓜式免费自助建站系统wordpress下拉
  • 【LeetCode热题100(47/100)】路径总和 III
  • bpmn-js 中如何完整导出 PNG(含自定义 Overlay)
  • 【图像处理】Gamma矫正
  • 【AI论文】MM-HELIX:借助整体式平台与自适应混合策略优化,提升多模态长链反思推理能力
  • Go 入门学习
  • IPoIB驱动中RSS/TSS技术深度解析与性能优化实践
  • Redis最佳实践
  • 鸿蒙NEXT Wear Engine开发实战:手机侧应用如何调用穿戴设备能力
  • github 个人静态网页搭建(一)部署
  • 【Go】C++ 转 Go 第(三)天:defer、slice(动态数组) 与 map
  • 【大模型微调】LLaMA Factory 微调 LLMs VLMs
  • 服务器管理:构建与维护高效服务器环境的指南
  • wordpress 网站生成app中山免费建站
  • 使用搭载Ubuntu的树莓派开启热点
  • 存算一体架构的先行者:RustFS在异构计算环境下的探索与实践
  • asp access网站建设源代码网站的开发流程可以分为哪三个阶段
  • SAUP论文提到的S2S Backbone Models是什么
  • 实战量化Facebook OPT模型
  • C 标准库函数 | strcmp, strlen
  • 图像处理~多尺度边缘检测算法
  • 网站集约化建设必要性wordpress 媒体库外链
  • springboot整合redis-RedisTemplate集群模式