LeetCode 替换后的最长重复字符(滑动窗口)

给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次。在执行上述操作后,找到包含重复字母的最长子串的长度。
注意:
字符串长度 和 k 不会超过 104。
示例 1:

输入:
s = "ABAB", k = 2
输出:
4
解释:
用两个'A'替换为两个'B',反之亦然。

示例 2:

输入:
s = "AABABBA", k = 1
输出:
4
解释:
将中间的一个'A'替换为'B',字符串变为 "AABBBBA"。
子串 "BBBB" 有最长重复字母, 答案为 4。

思路分析:双指针窗口滑动法。使用两个指针分别作为窗口的left、right,不断右移动right指针(扩大窗口),将窗口中的字符数作为一个中间结果(替换后的最长重复字符),当窗口大小 - 窗口中出现次数最多的字符数即是需要替换的字母数。如果需要替换的字母数超过了k,则说明需要缩小窗口(右移left)。

class Solution {
public:
    int characterReplacement(string s, int k) {
        vector<int> chCnt(26, 0); //记录当前窗口字母出现的个数
        int left = 0, result = 0, maxCnt = 0, strSize = s.size(); // maxCnt记录字符出现次数最多那个字符 的次数
        for (int right = 0; right < strSize; ++right){
        	chCnt[s[right] - 'A'] += 1;//计数
        	maxCnt = max(maxCnt, chCnt[s[right] - 'A']);//动态更新当前窗口中出现次数最多的字符数量
        	//(right - left + 1当前窗口的大小) 减去 (出现次数最多的字符的数量maxCnt) 等于 (需要替换的字符数)
        	while (right - left + 1 - maxCnt > k){//当需要替换的字符数超过了k
        		//左移窗口左边界,缩小窗口
        		chCnt[s[left++] - 'A'] -= 1;
        	}
        	//right - left + 1现在为窗口大小,同时也为一个中间结果——重复字母的最长子串的长度
        	result = max(result, right - left + 1);//更新结果
        }
        return result;
    }
};

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41855420/article/details/88762639