给一个长度为n的字符串,找出长度为m的最小字典子序列【单调栈】
一个大大的分割线,如果这个傻逼题没有被作为某某复赛的签到题,可能我一会都一直傻逼下去了。
【2019计蒜之道复赛——星云系统】
题目是,给出一个长度为n(1<n<5e6)的只有小写字母的字符串,然后找出一个长度为m的最小字典子序列。
更新: 这是一道简单得要死掉的单调栈裸题,为什么没想到呢,因为思路是,利用单调栈尽量求取结果字符串的最优值,也就说结果字符串在理想情况下是递增的,但是非理想情况是什么呢?因为有必须限定k个字母存在,因此被删掉的字母数量为len-k个字符,当被单调栈弹出的字符数量达到n-k个时,剩余的字符【即单调栈中的递增字符以及未遍历到的剩余字符】就组成了最小字典序ans。
散了散了。。。时间复杂度是线性扫描的O(n)
想想也是,题面都这个数量级了,还要啥常数。线性就完了。
#include<bits/stdc++.h>
#define M(a,b) memset(a,b,sizeof a)
#define LL long long
using namespace std;
const int maxn=5000007;
char a[maxn];
stack<char>q;
int n,m;
int main()
{while(!q.empty())q.pop();scanf("%s %d",a,&m);n=strlen(a);int cnt=0;int flag=n;for(int i=0; i<n; i++){if(q.empty())q.push(a[i]);else{if(a[i]>q.top())q.push(a[i]);else{while(!q.empty()&&q.top()>a[i]){q.pop();cnt++;if(cnt>=n-m){flag=i;break;}}q.push(a[i]);}}if(cnt>=n-m)break;}string ans="";for(int i=n-1;i>flag;i--)ans+=a[i];while(!q.empty())ans+=q.top(),q.pop();reverse(ans.begin(),ans.end());ans=ans.substr(0,m);cout<<ans<<"\n";
}
头条一面挂了,除了自己菜,数据结构和基础知识理解不够深刻外,还有就是面试时紧张得肚子疼到抽搐。。。可能是绝症了
言归正传,面试官本来想随便出个签到题玩一下开个场,结果被我紧张的崩了。
结束面试之后冷静下来认真想了下并不难
题目是,给出一个长度为n(1<n<10000)的只有小写字母的字符串,然后找出一个长度为m的最小字典子序列。
如 orange
当m=3时,输出结果age
若borange,且长度为3时,同样输出age
面试的时候脑子一团浆糊,想到了标号和排序,直接被反例否定了。
如果用最暴力的思想,找到n个字符里字典序最小且位序小于等于m的字母,然后砍去这个字母之前的字母,在剩余的字母中又找一个字典序最小的字母,这样一直找m个就好了。
唯一要考虑的条件就是,这样不断贪心取最小的要求是,要保证取了某个字母后,剩余待选串中的字符个数要大于等于m。
于是想到一个 复杂度为O(n*m) 的做法,每次遍历n字符串,查找符合条件的字符,再从头扫一遍找下一个字符。从头扫的原因是,当找到了一个字符,比如b,无法判断是否后面的字符是否存在一个字典序小于b的字符,所以仍要遍历完整个串才能得到一个最小值。这样是不可取的,必须进行优化。
那么做一个预处理,首先26个vector存储每个字母出现位置的下标,O(n)遍历字符串,push进每个字母出现下标,因为是顺序遍历,所以每个vector都是有序的。
然后遍历m次这26个vector,找出第一个字母的出现位置,满足<=n-(m-i)+1,说明存在一个较小的字母符合筛选条件,并且不用关心该位置剩余字符串是否存在比其更小的字母,如果存在,在字典序遍历其他vector就应该找到了。在ans中填入这个字母,然后从a字母开始继续查找下标大于上一个填入ans中字母下标的符合条件的字母。这个在有序vector中查找位置直接用二分即可。
最后时间复杂度O(26*m),空间复杂度O(n)
代码如下:
#include<bits/stdc++.h>
using namespace std;
char a[10080];
vector<int>pos[26];
int main()
{int n,m;char ans[10080];while(scanf("%d",&n)!=EOF){for(int i=0;i<=26;i++)pos[i].clear();scanf("%d",&m);scanf("%s",a);for(int i=0; i<n; i++) pos[a[i]-'a'].push_back(i+1);memset(ans,0,sizeof ans);int tmp=0;for(int i=0; i<m; i++){for(int j=0; j<26; j++){if(pos[j].size()!=0){int num=pos[j][upper_bound(pos[j].begin(),pos[j].end(),tmp)-pos[j].begin()];if(num>tmp&&num<=n-m+i+1){tmp=num;ans[i]='a'+j;break;}}}}printf("%s\n",ans);}
}
给一个长度为n的字符串,找出长度为m的最小字典子序列【单调栈】相关推荐
- 从键盘输入 5 个学生姓名,利用字符串函数,找出长度最长的那个并输出。
从键盘输入 5 个学生姓名,利用字符串函数,找出长度最长的 那个并输出. #include <stdio.h> #include <string.h> int main(){c ...
- python编写函数、给定任意字符串_编写函数,给定任意字符串,找出其中只出现一次的字符,如果有多个这样的字符,就全部找出。...
[简答题]编写程序,实现分段函数计算,如下表所示. x y x<0 0 0<=x<5 x 5<=x<10 3x-5 10<=x<20 0.5x-2 20< ...
- js比较两个String字符串找出不同,并将不同处高亮显示
根据java代码改写成js,下边js文件代码: function StringBuffer() {this.__strings__ = []; }; StringBuffer.prototype.ap ...
- php找出字符串不同地方,PHP中比较两个字符串找出第一个不同字符位置例子
PHP中比较两个字符串找出第一个不同字符位置例子 一般的做法就会这样: 复制代码 代码如下: for ($offset = 0; $offset < $length; ++$offset) { ...
- 盘点一个使用Python实现Excel中找出第一个及最后一个不为零的数,它们各自在第几列
一.前言 前几天在Python交流群中遇到一个问了一个使用Python实现Excel中找出第一个及最后一个不为零的数,它们各自在第几列的问题,觉得还挺有用的,这里拿出来跟大家一起分享下. 数据截图如下 ...
- 【宫水三叶的刷题日记】961. 在长度 2N 的数组中找出重复 N 次的元素
题目描述 这是 LeetCode 上的 961. 在长度 2N 的数组中找出重复 N 次的元素 ,难度为 简单. Tag : 「模拟」.「计数」.「构造」.「哈希表」 给你一个整数数组 nums ,该 ...
- 通过一趟遍历找出长度为n的单链表中值最大的节点.【数据结构】【单链表】
编写一个函数完成如下功能:通过一趟遍历找出长度为n的单链表中值最大的节点. 要求,在主函数中调用上面的函数测试. 提示:还需要定义其他函数,比如初始化链表,构造单链表,输出单链表. 输出结果: 代码展 ...
- 一个N*M的矩阵,找出这个矩阵中所有元素的和不小于K的面积最小的子矩阵
题目描述: 一个N*M的矩阵,找出这个矩阵中所有元素的和不小于K的面积最小的子矩阵(矩阵中元素个数为矩阵面积) 输入: 每个案例第一行三个正整数N,M<=100,表示矩阵大小,和一个整数K 接下 ...
- /给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[
给你一个由 n 个整数组成的数组 nums ,和一个目标值 target .请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] ( ...
最新文章
- pc显示器分辨率 前端_五款高性价比PC显示器推荐 499元起
- 避免重复造轮子,我们去哪找FPGA IP或是HDL功能模块?
- win10:JDK12.0.1环境变量配置
- Java实体映射工具MapStruct
- 使用Nuget 安装指定版本package或者更新package到指定版本
- c语言字 字符串转换成数组_C语言学习教程之详解C语言中的字符串数组
- plsql developer 查看存储过程执行计划_产品简介 | X-Developer一站式研发效能管理平台...
- 项目云台控制页面(仿遥控器)
- blackberry 7290 关于电子书阅读的几个注意事项
- ubuntu等linux发行版声卡、网卡、显卡驱动问题解决
- 计算机无法连接苹果手机软件,iphone连不上itunes
- 教你炒股票25:吻,MACD、背弛、中枢
- qPCR检测基因表达的引物数据库
- 计算机电源电压的调整,电压调整电路、电压调整方法及其计算机系统
- kubernets(k8s) 京东最新容器应用报告
- 11篇推荐系统入门必读经典论文(附下载链接)
- java环境的搭建及环境变量的配置
- Hexagon Binutils GNU 手册(19)
- uniapp 项目中添加百度统计
- 走进小作坊(十九)----商场博弈论的诡计