字符修复问题 | 豆包MarsCode AI刷题

31 阅读2分钟

问题描述

题目链接

有一个小写字母组成的字符串str,字符串长度为n;字符串中某些位置可以执行修复操作:将这个位置的字符,替换为a~z中的一个字符;这个修复操作最多可以执行m次;现在想知道修复之后,字符串 str由相同字符组成的子串最大长度是多少。

测试样例

输入样例1

5 2
abcda
01110

输入样例2

7 2
abbaccb
1001001

输入样例3

3 0
aab
101

输出样例1

3

输出样例2

4

输出样例3

2

解决思路

由于字符串长度 n 最大为 2000,我们可以考虑使用滑动窗口(Sliding Window)技术来解决这个问题。滑动窗口技术可以帮助我们在 O(n) 的时间复杂度内找到满足条件的子串。

  1. 初始化变量

    • 使用两个指针 left 和 right 来表示滑动窗口的左右边界。
    • 使用一个变量 repairs 来记录当前窗口中的修复次数。
    • 使用一个变量 max_len 来记录当前找到的最大子串长度。
  2. 滑动窗口

    • 移动 right 指针,扩大窗口,直到窗口内的修复操作次数超过 m
    • 如果修复操作次数超过 m,移动 left 指针,缩小窗口,直到修复操作次数再次小于等于 m
    • 在每次移动 right 指针时,更新 max_len
  3. 处理不可修改的字符

    • 如果某个位置的字符不可修改(即 str2 中对应位置为 0),则直接跳过该位置,不进行修复操作。

代码实现

    public static int solution(int n, int m, String str1, String str2) {
        int maxLen = 0;
        
        // 遍历所有可能的字符 'a' 到 'z'
        for (char targetChar = 'a'; targetChar <= 'z'; targetChar++) {
            int left = 0, right = 0;
            int repairs = 0;
            
            while (right < n) {
                // 如果当前字符不是目标字符,且可以修改
                if (str1.charAt(right) != targetChar && str2.charAt(right) == '1') {
                    repairs++;
                }
                
                // 如果当前字符不是目标字符,且不可修改,则重置窗口
                if (str1.charAt(right) != targetChar && str2.charAt(right) == '0') {
                    left = right + 1;
                    repairs = 0;
                }
                
                // 如果修复次数超过 m,移动左指针
                while (repairs > m) {
                    if (str1.charAt(left) != targetChar && str2.charAt(left) == '1') {
                        repairs--;
                    }
                    left++;
                }
                
                // 计算当前窗口的长度
                maxLen = Math.max(maxLen, right - left + 1);
                
                right++;
            }
        }
        
        return maxLen;
    }

滑动窗口算法的使用建议

滑动窗口技术常用于处理涉及连续子数组或子串的问题,尤其是在需要动态计算某些统计值(如最大值、最小值、和等)的场景中。常见应用包括查找固定长度子串的最大和、最长不重复子串、子数组和等。使用滑动窗口时,窗口的大小可以是固定的,也可以根据条件动态调整,从而避免了重复计算,提高了算法的效率。