题目内容
424 Longest Repeating Character Replacement
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个字母。
题目分析
第一次使用搜索方法时,是从第一个字母为起始逐个遍历,默认以开头字母为主元素,向后搜索,替换与主元素不同的字母,直到替换数超过k,若搜索进行到末尾且替换数小于等于k,则以相似步骤从开头字母向前搜索。由于重复遍历,该算法在字符串长度达到5000以上时超时。
题目讨论中@harunrashidanver网友使用数组维护滑动区间中各字母的数量,很好地减少了重复遍历的次数。每次移动时,根据端点移动情况更新区间内各字母数量(count数组)和优势字母数量(maxcharcount)。算法开始时滑动区间([end,start])为【0,0】,外循环将滑动区间右端点右移(无字母去除,根据右端点字母数量更新优势字母数量),滑动区间替换数目(end-start-maxcharcount+1)超过k时,内循环不断调整区间左端点直到替换数目符合要求。(由于有字符去除需遍历字母数量数组重新统计优势字母数量)再通过外循环右移动右端点。如此循环并对每个符合要求的区间中维护当前最大值。右端点到达字符串末尾循环结束。
代码示例
class Solution {
public
int characterReplacement(string s, int k) {
int res=0;
int maxcharcount=0;
int start=0;
int len=s.size();
vector<int> count(26,0);
for(int end=0;end!=len;end++)
{
count[s[end]-'A']++;
if(maxcharcount<count[s[end]-'A'])
maxcharcount=count[s[end]-'A'];
while(end-start-maxcharcount+1>k)
{
count[s[start]-'A']--;
start++;
for(int i=0;i!=26;i++)
{
if(maxcharcount<count[i])
maxcharcount=count[i];
}
}
if(end-start+1>res)
res=end-start+1;
}
return res;
}
};
时间复杂度O(m*n) m为最长区间长度,n为字符串长度。