知识点:字符串,滑动窗口;ui
给你一个仅由大写英文字母组成的字符串,你能够将任意位置上的字符替换成另外的字符,总共可最多替换 k 次。在执行上述操做后,找到包含重复字母的最长子串的长度。code
注意:字符串长度 和 k 不会超过 104。leetcode
输入:s = "ABAB", k = 2 输出:4 解释:用两个'A'替换为两个'B',反之亦然。 输入:s = "AABABBA", k = 1 输出:4 解释: 将中间的一个'A'替换为'B',字符串变为 "AABBBBA"。 子串 "BBBB" 有最长重复字母, 答案为 4。
这道题其实挺复杂的,里面有一些细节很难想;
想一下滑动窗口模板:
这道题目的条件时什么:当前窗口里出现次数最多的字母+k等于窗口长度
当达到这个条件后,若是下一个字符不是出现最多的字符,那左窗口就要移动了。
因此咱们须要一个变量来记录当前窗口哪一个字母出现的最大次数字符串
class Solution { public int characterReplacement(String s, int k) { int[] num = new int[26]; int n = s.length(); int maxn = 0; int left = 0, right = 0; while (right < n) { int indexR = s.charAt(right) - 'A'; num[indexR]++; //求窗口中曾出现某字母的最大次数 //计算某字母出如今某窗口中的最大次数,窗口长度只能增大或者不变 //这样作的意义:咱们求的是最长,若是找不到更长的维持长度不变返回结果不受影响 maxn = Math.max(maxn, num[indexR]); //若是选择了maxn,那说明又多消耗了一个k;检查一下k还够不够用了,不够用的话总体移动,注意窗口大小是不变的。 //长度len=right-left+1,如下简称len //len>字母出现最大次数+替换数目,说明k不够用了,这时候得把窗口向左移; //分析一下,替换数目是不变的=k,字母出现最大次数是可能变化的,所以,只有字母出现最大次数增长的状况,len才能拿到最大值 //left和right一块儿移动,len不变的 if (right - left + 1 - maxn > k) { //这里要减的,由于left越过该点,会对最大值有影响 num[s.charAt(left) - 'A']--; left++; } //走完这里的时候,其实right会多走一步 right++; } //由于right多走一步,结果为(right-1)-left+1==right-left return right - left; } }
细节:get
好比一个子串k=2,而后有一段他的最大重复个数maxn是4,这时候他的长度是6,而后移动滑动窗口到另外一段,若是这一串的最大重复个数小于4,那必定不会获得一个大于6的结果,因此记录历史最大值是能够了。记住咱们找的是最长,若是找不到更长,那就维持不变就能够了io