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

题目

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

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

示例1

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

示例2

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

题解

  1. 对于一个子串如:ABAB,其内部字符包含A和B,我们找到该子串内部出现次数最多的字符A或者B,最大次数maxCount为2,由于有k个字符可以被替换。即当该子串长度 <= maxCount+k时,代表该子串可以表示为一个含有重复字母的子串
  2. 找到该子串内部某一字符出现的最多次数maxCount,因为有k次的容错机会,所以这k次机会都要给已经出现次数最多的字符
    1. 当该子串长度right-left+1 < maxCount+k:表示此时该k还有剩余,即可以继续增加最长子串的长度,即右指针右移
    2. 当该子串长度right-left+1 > maxCount+k:此时k显得“力不从心”不能替换不同的字符了;此时需要更新左指针
参考代码
class Solution {
    public int characterReplacement(String s, int k) {
      int left = 0, right = 0;
      int maxCount = 0;
      int res = 0;
      Map<Character, Integer> map = new HashMap<>();
      while(right < s.length()) {
        char key = s.charAt(right++);
        int val = map.getOrDefault(key, 0);
        map.put(key, val+1);
        maxCount = Math.max(maxCount, map.get(key));
        if(right - left > maxCount + k) {
          int a = s.charAt(left++);
          map.put(a, map.get(a)-1);
        }
        res = Math.max(res, right - left);
      }
      return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!对于您的问题,您可以使用滑动窗口的方法来解决。具体步骤如下: 1. 初始化一个字典freq,用于记录字符串中每个字符出现的数。 2. 定义左指针left和右指针right,初始化为0。 3. 定义变量maxLen,用于记录最长重复字母组成子串的长度。 4. 进入循环,循环条件是右指针小于字符串长度。 - 将右指针所指的字符加入字典freq,并更新该字符的出现数。 - 如果当前窗口内不满足重复字母个数不超过k个的条件,即right - left + 1 - max(freq.values()) > k,说明窗口内需要替换字符超过了k个。 - 将左指针所指的字符从字典freq中减去,并更新该字符的出现数。 - 左指针右移一位。 - 更新最长子串长度maxLen,即max(maxLen, right - left + 1)。 - 右指针右移一位。 5. 返回最长子串长度maxLen。 以下是一个示例的C++代码实现: ```cpp #include <iostream> #include <unordered_map> #include <algorithm> using namespace std; int longestSubstring(string s, int k) { unordered_map<char, int> freq; int left = 0, right = 0; int maxLen = 0; while (right < s.length()) { freq[s[right]]++; if (right - left + 1 - max_element(freq.begin(), freq.end(), [](const auto& a, const auto& b) { return a.second < b.second; })->second > k) { freq[s[left]]--; left++; } maxLen = max(maxLen, right - left + 1); right++; } return maxLen; } int main() { int n, k; cin >> n; string s; cin >> s; cin >> k; int result = longestSubstring(s, k); cout << result << endl; return 0; } ``` 希望能帮助到您!如有任何疑问,请随时向我提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值