【双指针 | 滑动窗口】LeetCode 424. 替换后的最长重复字符

424. 替换后的最长重复字符


题目来源:力扣(LeetCode)https://leetcode-cn.com/problems/longest-repeating-character-replacement/

题目


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

**注意:**字符串长度 和 k 不会超过 104。

示例 1:

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

示例 2:

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

解题思路


思路:双指针(滑动窗口)

先审题,题目给定一个字符串 s s s 以及一个整数 k k k,其中:

  • s s s: 仅由大写英文字母组成;
  • k k k: 整数,表示可替换的次数。

题目规则:

  • 可将任意位置的字符替换为另外的字符,但最多可替换 k k k 次。

题目所求:

  • 进行替换后,返回包含重复字母的最长子串的长度。

根据题意可知,最终所求的最长子串中的字母必须都是重复的。

那么要找到这样的包含重复字母的最长子串,首先可以考虑先找包含重复字母尽可能多的子串,替换该子串中不同的字符以形成更长的子串。

包含重复字母尽可能多的子串: 下面用 t m p tmp tmp 代替

这里需要注意的是,首先找的 t m p tmp tmp 子串中不同字符数应该小于或等于 k k k。若大于 k k k 时,会导致 t m p tmp tmp 中的不同字符无法被完全替换,无法形成所需的子串(仅包含重复字符)。

以示例 2 为例,用图示看下过程:

我们可以使用双指针来维护所查找子串的区间,这里补充说下上面图示的思路:

  • 先处理特殊情况,当字符串 s s s 长度等于 0 或 1 时,直接返回此时字符串 s s s 的长度;
  • 定义指针 l e f t left left r i g h t right right,初始指向字符串的开始位置;
  • 声明变量 c h a r _ m a x _ c n t char\_max\_cnt char_max_cnt 存储子串中重复字母最多的个数;
  • 因为字符串 s s s 仅由大写英文字母组成,声明长度为 26 的数组 a r r arr arr 存储子串中出现字母的个数,用于后续判断子串中哪个字母最多;
  • 记录字符出现的个数,维护 c h a r _ m a x _ c n t char\_max\_cnt char_max_cnt,移动 r i g h t right right 指针,开始寻找尽可能多重复字母的子串;
  • 当子串中与最多重复字符不同的字符数目大于 k k k 时,也就是此时 [ l e f t , r i g h t ] [left, right] [left,right] 区间的与最多重复字符不同的字符无法被完全替换,考虑移动指针 l e f t left left 缩小区间。这里注意移动 l e f t left left 指针前,先将 l e f t left left 指针对应的字符数减 1(因为 l e f t left left 往右移动后,前面字符将不在子串的范围内)
  • 持续交替移动 l e f t left left r i g h t right right 指针,尝试查找更长的子串。直至 r i g h t right right 指针到达末尾,停止移动。
  • 最终答案将产生在指针交替移动的过程中。

具体的代码实现如下。

class Solution:
    def characterReplacement(self, s: str, k: int) -> int:
        n = len(s)

        left = 0
        right = 0

        arr = [0] * 26

        char_max_cnt = 0

        ans = 0

        while right < n:
            arr[ord(s[right]) - ord('A')] += 1
            char_max_cnt = max(char_max_cnt, arr[ord(s[right]) - ord('A')])
            right += 1

            if right - left > char_max_cnt + k:
                arr[ord(s[left]) - ord('A')] -= 1
                left += 1
            
            ans = max(ans, right - left)

        return ans

欢迎关注


公众号 【书所集录】


如有错误,烦请指出,欢迎指点交流。若觉得写得还不错,麻烦点个赞,谢谢。

你可能感兴趣的:(LeetCode,leetcode,算法,双指针,滑动窗口,python)