跳转至

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 <= 105
  • s 仅由大写英文字母组成
  • 0 <= k <= s.length

解法

方法一:双指针

我们使用一个哈希表 cnt 统计字符串中每个字符出现的次数,使用双指针 lr 维护一个滑动窗口,使得窗口的大小减去出现次数最多的字符的次数,结果不超过 \(k\)

我们遍历字符串,每次更新窗口的右边界 r,并更新窗口内的字符出现次数,同时更新出现过的字符的最大出现次数 mx。当窗口的大小减去 mx 大于 \(k\) 时,我们需要缩小窗口的左边界 l,同时更新窗口内的字符出现次数,直到窗口的大小减去 mx 不大于 \(k\)

最后,答案为 \(n - l\),其中 \(n\) 为字符串的长度。

时间复杂度 \(O(n)\),空间复杂度 \(O(|\Sigma|)\)。其中 \(n\) 为字符串的长度,而 \(|\Sigma|\) 为字符集的大小,本题中字符集为大写英文字母,所以 \(|\Sigma| = 26\)

 1  2  3  4  5  6  7  8  9 10 11
class Solution: def characterReplacement(self, s: str, k: int) -> int: cnt = Counter() l = mx = 0 for r, c in enumerate(s): cnt[c] += 1 mx = max(mx, cnt[c]) if r - l + 1 - mx > k: cnt[s[l]] -= 1 l += 1 return len(s) - l 
 1  2  3  4  5  6  7  8  9 10 11 12 13 14
class Solution {  public int characterReplacement(String s, int k) {  int[] cnt = new int[26];  int l = 0, mx = 0;  int n = s.length();  for (int r = 0; r < n; ++r) {  mx = Math.max(mx, ++cnt[s.charAt(r) - 'A']);  if (r - l + 1 - mx > k) {  --cnt[s.charAt(l++) - 'A'];  }  }  return n - l;  } } 
 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
class Solution { public:  int characterReplacement(string s, int k) {  int cnt[26]{};  int l = 0, mx = 0;  int n = s.length();  for (int r = 0; r < n; ++r) {  mx = max(mx, ++cnt[s[r] - 'A']);  if (r - l + 1 - mx > k) {  --cnt[s[l++] - 'A'];  }  }  return n - l;  } }; 
 1  2  3  4  5  6  7  8  9 10 11 12 13
func characterReplacement(s string, k int) int {  cnt := [26]int{}  l, mx := 0, 0  for r, c := range s {  cnt[c-'A']++  mx = max(mx, cnt[c-'A'])  if r-l+1-mx > k {  cnt[s[l]-'A']--  l++  }  }  return len(s) - l } 
 1  2  3  4  5  6  7  8  9 10 11 12 13
function characterReplacement(s: string, k: number): number {  const idx = (c: string) => c.charCodeAt(0) - 65;  const cnt: number[] = Array(26).fill(0);  const n = s.length;  let [l, mx] = [0, 0];  for (let r = 0; r < n; ++r) {  mx = Math.max(mx, ++cnt[idx(s[r])]);  if (r - l + 1 - mx > k) {  --cnt[idx(s[l++])];  }  }  return n - l; } 

评论