知識點:字符串,滑動窗口;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