刷题参考:https://blog.csdn.net/IBelieve2016/article/details/104544763
/*
Given a string that consists of only uppercase English letters,
you can replace any letter in the string with another letter at most k times.
Find the length of a longest substring containing all repeating letters
you can get after performing the above operations.
Note:
Both the string's length and k will not exceed 104.
Example 1:
Input:
s = "ABAB", k = 2
Output:
4
Explanation:
Replace the two 'A's with two 'B's or vice versa.
Example 2:
Input:
s = "AABABBA", k = 1
Output:
4
Explanation:
Replace the one 'A' in the middle with 'B' and form "AABBBBA".
The substring "BBBB" has the longest repeating letters, which is 4.
替换k次后的最长连续相同字串
*/
#include <iostream>
#include <unordered_map>
#include<string>
using namespace std;
int solution(string s,int k){
int res=0;
int left=0;
int minx=0;
char a,b;
unordered_map<char,int> countmap;
a=s[left];
for(int i=0;i<s.size();i++){
countmap[s[i]]+=1;
//最靠右的那个指向b,另一个指向a
//如果右边的值不和b一样则替换
if(s[i]!=b){
a=b;
b=s[i];
}
//如果子串中字母都是一样,则需要替换的值是0个
//否则取少的那个值
if(countmap.size()==1){
minx=0;
}else{
minx=min(countmap[a],countmap[b]);
}
while(countmap.size()>2||minx>k){
//子串中,出现多于两个字符,或较少的那个=k
countmap[s[left]]--;
if(countmap[s[left]]==0){
countmap.erase(s[left]);
}
left++;
minx=min(countmap[a],countmap[b]);
}
res=max(res,i-left+1);
}
return res;
}
//!上面有个问题,限制了只有两个字符的情况下k=2 s=AABAA 得到5,这个没问题,
// 假如ACBAA则只能检查到BAA得到3
/*
最长连续相同子串,则说是只有一个字符
那么替换k个字符,意思就是当前字符串长度i-left,再减去当前字符串的最长值。
即:res=i-left-max(count(s[i]),res)
k值就是除开最长字符以外,其他字符的个数
*/
int solution1(string s,int k){
int res=0,left=0,mk=0;
unordered_map<char,int> countmap;
for(int i=0;i<s.size();i++){
countmap[s[i]]++;
mk=max(countmap[s[i]],mk);
//这里是只需要子串中,最多的字符的数目,所以只需要保留最大的那个。
//后面可能会变化,但是如果变小的话,没有必要纪录,我们只需要纪录最长的即可 。
//除了最长串之外的其他字符数超过了k则移动left
while(i-left-mk+1>k){
countmap[s[left]]--;
left++;
}
res=max(i-left+1,res);
}
return res;
}
int main(){
//使用这个,以下会出现问题。
string s="ACBAA";
int k=2;
cout<<solution(s,k)<<endl;
//这个没问题
cout<<solution1(s,k)<<endl;
return 0;
}