eli和字符串(尺取算法)牛客网2020寒假训练营1
acnowcoder
eli和字符串
链接:https://ac.nowcoder.com/acm/contest/3002/G
来源:牛客网
题目描述
eli拿到了一个仅由小写字母组成的字符串。她想截取一段连续子串,这个子串包含至少
个相同的某个字母。她想知道,子串的长度最小值是多少?
注:所谓连续子串,指字符串删除头部和尾部的部分字符(也可以不删除)剩下的字符串。例如:对于字符串“arcaea"而言,“arc”、“rcae”都是其子串而“car”,“aa”则不是它的子串。
输入描述:
第一行输入两个正整数n 和k
(1<=k<=n<=200000)输入仅有一行,为一个长度为n的、仅由小写字母组成的字符串。
输出描述:如果无论怎么取都无法满足条件,输出 -1否则输出一个正整数,为满足条件的子串长度最小值。
样例输入:
5 2
abeba
样例输出:
3
说明
选择“beb”\mathit“beb”“beb”子串,长度为3,其中包含相同的两个’b’
1.暴力枚举
枚举出所有的子串,记录满足条件的最小长度。
#include<iostream>#include<string>using namespace std;int main(){int n,k;cin>>n>>k;string s;cin>>s;int len = s.length();int min=len;int flag=0;for(int i=0;i<len;i++){for(int j=1;j<=len-i;j++){ if(j>=min) break; //这里进行了初步优化,j是生成子串的长度//如果生成子串的长度已经大于已经满足条件的min直接结束循环int letters[26]={0};string s1= string(s,i,j);int len2 = s1.length();for(int l = 0;l<len2;l++){letters[s1[l]-'a']++;}for(int
l=0;l<26;l++){if(letters[l]==k&&len2<=min) {min=len2;} }}}if(len==1)flag=1;if(flag==0)
cout<<-1<<endl;else cout<<min<<endl;}
时间复杂度为o(n^3);
运行超时
case通过率60.00%
2,优化
在题目描述的条件下,我们没必要枚举所有的子串
对于一个字符串的每一个索引位置都有满足条件的子串都是确定且唯一的。
换句话说,对于一个确切的开头,我们只需要往后便利,直到出现了k个与开头相同的字符,那么得到的子串就是这个开头的最佳答案。
举个例子:s=abaaebb n=6 k=3;
从s[0]为开头进行遍历,
a k=1 len=1
ab k=1 len=2
aba k=2 len=3
abaa k=3; len=4
即len=4为以s[0]开头处的最佳答案
对于s中的每一个位置,我们都可以找到它对应的最佳答案,当然前提是以s中每一个位置有满足条件的答案,如果从例子中的e开始遍历就没有满足条件的答案;
代码:
#include<iostream>#include<string>using namespace std;int main(){int n,k;cin>>n>>k;string s;cin>>s;int len = s.length();int min=len;int num=1;int flag=0;for(int i=0;i<len;i++){num=1;for(int j=i+1;j<len;j++){int len1 = j-i+1;if(len1>min) break; if(s[j]==s[i]) num++;if(num==k&&len1<min) {flag=1;min= len1;break;}}}if(len==1)flag=1;if(flag==0)
cout<<-1<<endl;else cout<<min<<endl;return 0;}
00%
3.尺取法
在一些对区间有所限制的问题当中,我们可以通过维护合法区间的左右边界。通过区间移动找出所有合法的区间,最后找到最终的答案。
时间复杂度o(n^2)
运行超时
case通过率60.00%
1.首先需要找到合法区间
定义:
区间左边界为l=0,区间右边界r=0;
判断区间是否合法条件:
建一个数组letter[26]记录区间中每个字母出现的次数,
每次右边界右移都会使letter[s[r]-‘a’]++
因此只需判断当前右边界位置对应的letter数组中的数值大小与k是否相同
此时仍不是合法区间,还需考虑左边界
letter[s[l]-‘a’]–;
l++,
使左边界右移,缩小区间范围,直到左边界位置上的字符s[l]==s[r];
此时l,r之间为合法区间;
区间移动:
找到合法区间后,得出当前满足条件的最短子字符串长度;
此后每次r++,都要伴随l++
以维护区间长度;
直到再次找到合法区间
结束条件:lrn-1;
例如 n=5 k=2;
s=abeba
初始的区间
l=0,r=0,min=n;
r++;
当前区间[a]beba 当前数组 letter[0]=1;
r++;
当前区间[ab]eba 当前数组 letter[1]=1;
r++ ;
当前区间[abe]ba 当前数组 letter[4]=1;
r++
当前区间[abeb]a 当前数组 letter[1]=2;
l–
当前区间a[beb]a 当前数组 letter[0]=0; 找到合法区间
min=3;
r++,l++
当前区间ab[eba] 当前数组 letter[0]=1,letter[1]=1;
l++
当前区间abe[ba] 当前数组 letter[4]=0;
l++
当前区间abeb[a] 当前数组 letter[1]=0;
l++
当前区间abeba[] 当前数组 letter[0]=0;
程序结束
#include<iostream>#include<cstring>#include<string>using namespace std;int main(){int n,k;cin>>n>>k;string s;cin>>s;int l=0,r=0;int map[26];memset(map,0,sizeof(map));map[s[0]-'a']=1;int min=n;int flag=0;while(r!=n-1&&l!=n-1){if(r!=n-1) {r++;map[s[r]-'a']++;if(map[s[r]-'a']==k){flag=1;while(s[l]!=s[r]){// cout<<l<<endl;map[s[l]-'a']--;l++;}if(r-l+1<min)
min=r-l+1;}// cout<<map[s[r]-'a']<<endl;}if(r-l+1>=min||r==n-1)
{map[s[l]-'a']--;l++;}}if(n==1) flag=1;if(flag==0) cout<<-1<<endl;else cout<<min<<endl;return 0;}
运行时间12ms;
eli和字符串(尺取算法)牛客网2020寒假训练营1相关推荐
- 校招linux基础知识,校招笔试整理 牛客网 2020小米校招(1)
前端 笔试 选择 牛客网 2020小米校招(1) 2020小米校招 localStorage和cookie 在现代浏览器中, cookie可以在跨域请求中被携带在请求头中 localStorage被设 ...
- 直通BAT面试算法精品课购买 算法 牛客网 优惠码 直通BAT
此优惠码为: AORh3Cu 优惠购课请点击链接:http://www.nowcoder.com/courses/1?coupon=AORh3Cu 别忘了填写邀请码呦
- 牛客网 刷题前的准备工作(输入 输出 如何接收?)
牛客网 刷题前的准备工作 牛客网 刷题前的准备工作 1. 数据读取接受问题 2.牛客刷题前的准备: 2.1. 弄清楚输入输出的行数关系 3.代码怎么写 3.1. 在牛客上测试自己的模板代码,是否能正确 ...
- 运维校招面经汇总(来源牛客网)
shopee SRE 作者:Stackingrule 链接:https://www.nowcoder.com/discuss/626107?source_id=discuss_experience_n ...
- 【牛客网面试必刷TOP101】链表篇(一)
链表 一.前言 二.学习刷题网站 1.推荐的原因 三.刷题 <1>反转链表 递归法 <2>链表内指定区间反转 ①头插法 ②递归法 <3>链表中的节点每k个一组翻转 ...
- Duplicate Strings 字符串 取模 牛客练习赛95
链接:https://ac.nowcoder.com/acm/contest/11185/A 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言52 ...
- 【2019牛客暑期多校训练营(第三场)- F】Planting Trees(单调队列,尺取)
题干: 链接:https://ac.nowcoder.com/acm/contest/883/F 来源:牛客网 The semester is finally over and the summer ...
- Java算法:牛客网Java版剑指Offer全套算法面试题目整理及电子档,Java算法与数据结构面试题,面试刷题、背题必备!牛客网剑指offer
剑指offer(java版) 牛客网Java版剑指Offer全套题目67道 资源来源于网络 目录 1.二维数组中的查找 2.替换空格 3.从尾到头打印链表 4.重建二叉树 5.用两个栈实现队列 6.旋 ...
- Java算法:华为机试算法(下),华为算法Java版,牛客网华为算法73~108题
接上篇:Java算法:华为机试算法(中),华为算法Java版,牛客网华为算法55~72题 HJ73 计算日期到天数转换 计算日期到天数转换 题目描述 根据输入的日期,计算是这一年的第几天.. 测试 ...
- 【回眸】近期牛客网刷刷刷(二)C(++)字符串Linux专题
牛客网知识点(二)(++)&字符串&Linux专题 串的模式匹配, 是求第一个字符串(模式串)在第二个字符串(主串)中的位置 String的值是不可变的,这就导致每次对String的操 ...
最新文章
- 针对Web应用的【攻击模式篇】
- 关于运行robot framework 报错解决方法,ModuleNotFoundError: No module named 'robot'
- 【组合数学】生成函数 ( 使用生成函数求解不定方程解个数 )
- sql array 数组基本用法(四)
- 13/100. Best Time to Buy and Sell Stock
- 整合spring cloud云架构 - SSO单点登录之OAuth2.0 登出流程(3)
- Java2017面试宝典--XML部分、 流行的框架与新技术、软件工程与设计模式、 j2ee部分、EBJ部分、 webservice部分...
- 曲线 神经网络_神经网络的数学基础-8(完结)
- git 停止维护了,官网无法下载
- 软件工程期中作业-阅读和提问
- 网页在线播放器 ····
- cada0图纸框_CAD怎么画图纸框?cad图纸框的绘制方法
- JS汉字转拼音带音标
- Android 去除各种厂家广告合集
- VS2008 Pocket PC 2003 SE仿真程序上网设置
- FPGA - Zynq - 加载 - BootRom
- 不从装VS6 MSDN
- 【SendSms】短信服务java.lang.NoSuchMethodError: com.google.gson.JsonParser.parseString(Ljava/lang/String;)
- Android 翻页效果 电子书 (转)
- vs 单元测试 无法正常启动 配置系统未能初始化