Longest Substring with Same Letters after Replacement (hard)

刷题参考: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;
} 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值