一个大大的分割线,如果这个傻逼题没有被作为某某复赛的签到题,可能我一会都一直傻逼下去了。
【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的最小字典子序列【单调栈】相关推荐

  1. 从键盘输入 5 个学生姓名,利用字符串函数,找出长度最长的那个并输出。

    从键盘输入 5 个学生姓名,利用字符串函数,找出长度最长的 那个并输出. #include <stdio.h> #include <string.h> int main(){c ...

  2. python编写函数、给定任意字符串_编写函数,给定任意字符串,找出其中只出现一次的字符,如果有多个这样的字符,就全部找出。...

    [简答题]编写程序,实现分段函数计算,如下表所示. x y x<0 0 0<=x<5 x 5<=x<10 3x-5 10<=x<20 0.5x-2 20< ...

  3. js比较两个String字符串找出不同,并将不同处高亮显示

    根据java代码改写成js,下边js文件代码: function StringBuffer() {this.__strings__ = []; }; StringBuffer.prototype.ap ...

  4. php找出字符串不同地方,PHP中比较两个字符串找出第一个不同字符位置例子

    PHP中比较两个字符串找出第一个不同字符位置例子 一般的做法就会这样: 复制代码 代码如下: for ($offset = 0; $offset < $length; ++$offset) { ...

  5. 盘点一个使用Python实现Excel中找出第一个及最后一个不为零的数,它们各自在第几列

    一.前言 前几天在Python交流群中遇到一个问了一个使用Python实现Excel中找出第一个及最后一个不为零的数,它们各自在第几列的问题,觉得还挺有用的,这里拿出来跟大家一起分享下. 数据截图如下 ...

  6. 【宫水三叶的刷题日记】961. 在长度 2N 的数组中找出重复 N 次的元素

    题目描述 这是 LeetCode 上的 961. 在长度 2N 的数组中找出重复 N 次的元素 ,难度为 简单. Tag : 「模拟」.「计数」.「构造」.「哈希表」 给你一个整数数组 nums ,该 ...

  7. 通过一趟遍历找出长度为n的单链表中值最大的节点.【数据结构】【单链表】

    编写一个函数完成如下功能:通过一趟遍历找出长度为n的单链表中值最大的节点. 要求,在主函数中调用上面的函数测试. 提示:还需要定义其他函数,比如初始化链表,构造单链表,输出单链表. 输出结果: 代码展 ...

  8. 一个N*M的矩阵,找出这个矩阵中所有元素的和不小于K的面积最小的子矩阵

    题目描述: 一个N*M的矩阵,找出这个矩阵中所有元素的和不小于K的面积最小的子矩阵(矩阵中元素个数为矩阵面积) 输入: 每个案例第一行三个正整数N,M<=100,表示矩阵大小,和一个整数K 接下 ...

  9. /给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[

    给你一个由 n 个整数组成的数组 nums ,和一个目标值 target .请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] ( ...

最新文章

  1. pc显示器分辨率 前端_五款高性价比PC显示器推荐 499元起
  2. 避免重复造轮子,我们去哪找FPGA IP或是HDL功能模块?
  3. win10:JDK12.0.1环境变量配置
  4. Java实体映射工具MapStruct
  5. 使用Nuget 安装指定版本package或者更新package到指定版本
  6. c语言字 字符串转换成数组_C语言学习教程之详解C语言中的字符串数组
  7. plsql developer 查看存储过程执行计划_产品简介 | X-Developer一站式研发效能管理平台...
  8. 项目云台控制页面(仿遥控器)
  9. blackberry 7290 关于电子书阅读的几个注意事项
  10. ubuntu等linux发行版声卡、网卡、显卡驱动问题解决
  11. 计算机无法连接苹果手机软件,iphone连不上itunes
  12. 教你炒股票25:吻,MACD、背弛、中枢
  13. qPCR检测基因表达的引物数据库
  14. 计算机电源电压的调整,电压调整电路、电压调整方法及其计算机系统
  15. kubernets(k8s) 京东最新容器应用报告
  16. 11篇推荐系统入门必读经典论文(附下载链接)
  17. java环境的搭建及环境变量的配置
  18. Hexagon Binutils GNU 手册(19)
  19. uniapp 项目中添加百度统计
  20. 走进小作坊(十九)----商场博弈论的诡计

热门文章

  1. 学习《论文写作》课程的收获
  2. HN 7 月招聘趋势榜,Go 击败 Java;微软大量员工请愿停止与海关合作
  3. CMNET和CMWAP简单区别
  4. 神经网络主要有三个基本要素:权重、偏置和激活函数
  5. 软件测试人员必备思维,软件测试人员的思维
  6. 非官方新人参考之quake3入门碎解
  7. cogs 944. [東方S3] 藤原妹红
  8. 苹果开放降级通道_今天下午 iOS 降级通道打开?骗子!
  9. 光耦的种类、选型和分析
  10. 新手看Mockplus2.3