【字节跳动笔试题】最大连续的相同字符的子串的长度
描述
有一个仅包含’a’和’b’两种字符的字符串s,长度为n,每次操作可以把一个字符做一次转换(把一个’a’设置为’b’,或者把一个’b’置成’a’);但是操作的次数有上限m,问在有限的操作数范围内,能够得到最大连续的相同字符的子串的长度是多少。
输入描述:
第一行两个整数 n , m (1<=m<=n<=50000),第二行为长度为n且只包含’a’和’b’的字符串s。
输出描述:
输出在操作次数不超过 m 的情况下,能够得到的 最大连续 全’a’子串或全’b’子串的长度。
示例1
输入:
8 1
aabaabaa
输出:
5
说明:
把第一个 ‘b’ 或者第二个 ‘b’ 置成 ‘a’,可得到长度为 5 的全 ‘a’ 子串。
思路
要求在有限的次数内实现翻转为连续子串需满足条件:
设子串为
a
1
,
a
2
,
.
.
.
,
a
s
a_1,a_2,...,a_s
a1,a2,...,as即长度为
s
s
s,则在有限的
M
M
M步操作下,设子串中
a
a
a或
b
b
b的个数为
m
m
m时,当有
m
<
=
M
m<=M
m<=M时方可实现操作。
故,当区间内
a
a
a或
b
b
b的个数大于
M
M
M后,需要进行左右指针移动。
因此确定算法的框架:贪心+滑动窗口
代码
#include<iostream>
#include<string>
using namespace std;
int main(){
int n,m;
cin>>n>>m;
string str;
cin>>str;
int maxl=0,l=0,r=0,numA=0,numB=0;
while(r<=n){
//先统计numA和numB
if(str[r]=='a') numA++;
else numB++;
if(numA<=m||numB<=m){
r++;//绝对可以翻转,且远远满足,基于贪心策略就将右指针移动
}
else{
if((r-l)>maxl)
maxl=r-l;//r和l指针用于确定区间长度找到最大可能连续长度
if(str[l]=='a'){
l++;
numA--;//对a下手
}
else{
l++;
numB--;//对b下手
}
r++;
}
}
maxl=max(maxl,r-l);
cout<<maxl<<endl;
return 0;
}