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

80 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第28天,点击查看活动详情

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

一、题目描述:

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

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

示例 1:

输入:s = "ABAB", k = 2

输出:4

解释:用两个'A'替换为两个'B',反之亦然。

示例 2:

输入:s = "AABABBA", k = 1

输出:4

解释:

将中间的一个'A'替换为'B',字符串变为 "AABBBBA"。

子串 "BBBB" 有最长重复字母, 答案为 4。

提示:

1 <= s.length <= 10^5

s 仅由大写英文字母组成

0 <= k <= s.length

来源:力扣(LeetCode)

链接:leetcode.cn/problems/lo…

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、思路分析:

  1. 这道题考察了什么思想?你的思路是什么?

    这道题我的第一想法是暴力解法,遍历输入字符串的所有子串,对于每一个子串,我们都进行如下操作:

    • 如果子串中所有的字符都一致,我们就贪心更多字符以便有更长的子串
    • 如若当前子串除了一种主流字符还有其他字符,要想使得替换后所有字符都一致,就得替换掉主流字符以外的所有字符。

    这种方法的时间复杂度太高了,可能已经达到O(n^3)。

    所以我们可以考虑使用滑动窗口,也可以称之为双指针的方法。

    我们设置字符串每一个位置作为右端点,然后找寻最远的左端点位置,要求最长字符串中非主流字符串不超过k个。

    如此我们可以使用双指针,当右指针右移,如若区间仍然满足最长字符串中非主流字符串不超过k个,左指针就不移动,否则左指针就左移一格,保证区间长度不变。

  2. 做题的时候是不是一次通过的,遇到了什么问题,需要注意什么细节?

    不是一次通过的,刚开始尝试写暴力解法,没有写出来。后来转念一想,这样时间复杂度太高了,于是想到了使用双指针(滑动窗口)来进行。

  3. 有几种解法,哪种解法时间复杂度最低,哪种解法空间复杂度最低,最优解法是什么?其他人的题解是什么,谁的效率更好一些?用不同语言实现的话,哪个语言速度最快?

    都大同小异,都是使用滑动窗口活着双指针方法来解题!

三、AC 代码:

func characterReplacement(s string, k int) int {
    cnt := [26]int{}
    maxCnt, left := 0, 0
    for right, ch := range s {
        cnt[ch-'A']++
        maxCnt = max(maxCnt, cnt[ch-'A'])
        if right-left+1-maxCnt > k {
            cnt[s[left]-'A']--
            left++
        }
    }
    return len(s) - left
}
​
func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}
​
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/longest-repeating-character-replacement/solution/ti-huan-hou-de-zui-chang-zhong-fu-zi-fu-n6aza/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

四、总结:

时间复杂度:O(n),其中 nn 是字符串的长度。我们至多只需要遍历该字符串一次。

空间复杂度:O(∣Σ∣ ),其中∣Σ∣ 是字符集的大小。我们需要存储每个大写英文字母的出现次数。

模板来源:

作者:掘金酱

链接:juejin.cn/post/706970…

来源:稀土掘金

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。