持续创作,加速成长!这是我参与「掘金日新计划 · 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)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、思路分析:
-
这道题考察了什么思想?你的思路是什么?
这道题我的第一想法是暴力解法,遍历输入字符串的所有子串,对于每一个子串,我们都进行如下操作:
- 如果子串中所有的字符都一致,我们就贪心更多字符以便有更长的子串
- 如若当前子串除了一种主流字符还有其他字符,要想使得替换后所有字符都一致,就得替换掉主流字符以外的所有字符。
这种方法的时间复杂度太高了,可能已经达到O(n^3)。
所以我们可以考虑使用滑动窗口,也可以称之为双指针的方法。
我们设置字符串每一个位置作为右端点,然后找寻最远的左端点位置,要求最长字符串中非主流字符串不超过k个。
如此我们可以使用双指针,当右指针右移,如若区间仍然满足最长字符串中非主流字符串不超过k个,左指针就不移动,否则左指针就左移一格,保证区间长度不变。
-
做题的时候是不是一次通过的,遇到了什么问题,需要注意什么细节?
不是一次通过的,刚开始尝试写暴力解法,没有写出来。后来转念一想,这样时间复杂度太高了,于是想到了使用双指针(滑动窗口)来进行。
-
有几种解法,哪种解法时间复杂度最低,哪种解法空间复杂度最低,最优解法是什么?其他人的题解是什么,谁的效率更好一些?用不同语言实现的话,哪个语言速度最快?
都大同小异,都是使用滑动窗口活着双指针方法来解题!
三、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(∣Σ∣ ),其中∣Σ∣ 是字符集的大小。我们需要存储每个大写英文字母的出现次数。
模板来源:
作者:掘金酱
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。