Leetcode424:替换后的最长重复字符

题目说明

leetcode424:替换后最长字符
Leetcode424:替换后的最长重复字符_第1张图片

题解

这个题目找对方法之后解起来应该说是很简单的,但是一开始自己掉进了贪心的坑里,想着通过找到最长的连续重复串,在其左/右进行替换即可,利用递归完成贪心算法,但是后来仔细琢磨了一下发现事情并没有这么简单(元芳,你怎么看…)。
最直接的一种情况[‘AAAAABCCCDCCCC’, k = 1],在该测试例下,替换掉’D显然比替换’B’获得的结果更大,因此贪心算法毫无用武之地。后来只好主动放弃,看了不少网上的题解,最受欢迎的解法还是使用滑动窗口(Sliding Windows),且滑窗法似乎是求解字符串类问题的常用思路。
具体的求解思路如下:

  1. 初始化滑动窗口,起始窗口宽度为0,定义start和end指针。
  2. 创建大小为26的一维数组,这是因为题目中指出所有字符均为26位大写字母中的一个,因此我们用一个数组来记录每个字符在当前窗口中出现的次数,每次找到出现次数最多的并记录器出现次数为maxCount。
  3. 不断移动窗口,移动的原则是:
  • 假如窗口内出现次数最多的字符与k相加小于当前窗口的大小(说明当前的滑窗大小过大),那么将start指针右移,随后end指针右移;若不然,只有end指针右移。

下面给出具体的python实现代码

def characterReplacement(self, s:str, k:int) -> int :
    if s.__len__() == 0:
        return 0
    # 滑窗左边界
    start = 0
    # 滑窗右边界
    end = 0
    # 滑窗滑过的部分中出现次数最多的字符
    maxCount = 0
    # 定义数组保存单个字符出现的次数
    charNum = [0] * 26
    # 主循环
    while end < len(s):
    	# 对应位置的字符数目+1
        charNum[ord(s[end]) - ord('A')] += 1
        # 获取最大字符数,比较当前位置的字符数与先前最大值的大小,
        # 取二者较大的一个
        maxCount = max(maxCount, charNum[ord(s[end]) - ord('A')])
        # 假如maxCount + k比窗口宽度窄,说明当前的宽度已经是最大宽度
        # 此时同时右移start和end
        # 此处需要注意,我们最终所需要的结果就是滑窗的宽度,很重要!
        if maxCount + k < end - start + 1:
            charNum[ord(s[start]) - ord('A')] -= 1
            start += 1
        end += 1
    return end - start

可以看到,代码之简洁令人瞠目结舌,核心部分在while循环内部。
这里附送一个使用滑窗求取字符串内最大连续重复字符个数的python程序(自己写的,不一定完全是bugless),大家有问题的可以评论区讨论。

def findLongest(s:str) -> tuple:
    start = 0
    end = 0
    while end < len(s):
        if s[start] == s[end]:
            end += 1
            if end >= len(s):
                break
        if start < end and s[start] != s[end]:
            start += 1
            end += 1
    return end - start

你可能感兴趣的:(Algorithms,python,算法,数据结构,字符串)