替换后的最长重复字符

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-repeating-character-replacement

给你一个字符串 s 和一个整数 k 。你可以选择字符串中的任一字符,并将其更改为任何其他大写英文字符。该操作最多可执行 k 次。

在执行上述操作后,返回包含相同字母的最长子字符串的长度。

点击查看代码
class Solution {
    public int characterReplacement(String s, int k) {
        //判断当前字符串长度是否小于 2 直接返回长度
        int len = s.length();
        if (len < 2) {
            return len;
        }
        //将字符串转为数组
        char[] charArray = s.toCharArray();
        //定义双指针实现的滑动窗口
        int left = 0;
        int right = 0;
        //定义存储结果变量 res
        int res = 0;
        //定义存储重复字符的最大个数
        int maxCount = 0;
        //定义存储将字符值作为索引的数组
        int[] freq = new int[128];
        // [left, right) 内最多替换 k 个字符可以得到只有一种字符的子串
        //当右指针不小于字符串长度时退出
        while (right < len){
            //右指针所在索引字符数量加一
            freq[charArray[right]]++;
            // 在这里维护 maxCount,因为每一次右边界读入一个字符,字符频数增加,才会使得 maxCount 增加
            //将当前最大重复字符个数与当前字符比较,得到新的最大重复字符个数
            maxCount = Math.max(maxCount, freq[charArray[right]]);
            //右指针索引加一
            right++;
            //判断右指针减左指针是否大于当前最大重复字符个数加可允许修改的字符数
            if (right - left > maxCount + k){
              	// 说明此时 k 不够用
                // 把其它不是最多出现的字符替换以后,都不能填满这个滑动的窗口,这个时候须要考虑左边界向右移动
                // 移出滑动窗口的时候,频数数组须要相应地做减法
                freq[charArray[left]]--;
                left++;
            }
            //将之前结果与当前求较大值
            res = Math.max(res, right - left);
        }
        //返回结果
        return res;
    }
}

示例 1:

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

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

posted @ 2022-07-21 15:06  xy7112  阅读(50)  评论(0编辑  收藏  举报