算法题解----字节跳动后端编程题
问题描述:
有一个仅包含’a’和’b’两种字符的字符串s,长度为n,每次操作可以把一个字符做一次转换(把一个’a’设置为’b’,或者把一个’b’置成’a’);但是操作的次数有上限m,问在有限的操作数范围 内, 能够得到最大连续的相同字符的子串的长度是多少。
输入描述:
第一行两个整数 n , m (1<=m<=n<=50000),第二行为长度为n且只包含’a’和’b’的字符串s。
输出描述:
输出在操作次数不超过 m 的情况下,能够得到的 最大连续 全’a’子串或全’b’子串的长度。
输入样例:
8 1 aabaabaa
输出样例:
5
其实严格来说这道题应该是一道错题(或者题目没说明白)
我虽然过了但是我在dev自己编了一道数据测了不对
这个数据肯定不对
那就来说说我的思路吧
我原本想这题用双指针写的,但是发现题目要求是找到最大的长度于是就放弃了这个做法
我转换了思路:题目要求我们只能把 a 变到 b 或者 把 b 变到 a 那么我们一定只能采取这一种操作才能得到最长的序列
否则如果你又把a变成b又把b变成a那么中间连续的串一定会被你切断了,得到的长度也一定不是最大值
那么我们只要比较这两种变法的值取最大就可以了
我写了一个函数,传入字符a或者字符b
把字符串中和我们传入字符相同的字符下标存到vector里面
然后loc[ m ] - loc[i - 1 - m] - 1就是当前的长度了
代码如下:
# include <iostream> # include <cstring> # include <cstdio> # include <vector> # include <algorithm> using namespace std; const int N = 5e4+10; char s[N]; int n,m; int res; int check(char c) { vector<int> loc; for (int i= 0; i< n; ++i) if (s[i] ==c) loc. push_back(i); loc.push_back(n); int max_length =loc[m]; for(int i=m+1;i<loc.size();i++) max_length=max(max_length,loc[i]-loc[i-m-1]-1); return max_length; } int main() { cin>>n>>m; scanf("%s",s); cout<<max(check('a'),check('b')); return 0; }