AI刷题95. 字符替换与最长子串问题| 豆包MarsCode AI刷题

55 阅读4分钟

一. 问题描述

小R得到了一个由大写字母组成的字符串,长度为 n。她可以对字符串中的字符进行修改,每次操作允许将某个位置的字符修改为任意字符。例如,字符串 ABC 的第一个字符 A 改为 B,则字符串变为 BBC。她最多可以进行 k 次这样的修改。

小R想知道,通过最多 k 次修改后,字符串中由最多两种不同字母组成的最长连续子串的长度是多少。

测试样例

样例1:

输入:n = 6 ,k = 1 ,inp = "ABCBAD"
输出:5

样例2:

输入:n = 5 ,k = 1 ,inp = "AEABD"
输出:4

样例3:

输入:n = 8 ,k = 2 ,inp = "AAAABBCD"
输出:8

题目链接:www.marscode.cn/practice/36…

二. 思路解析

2.1 问题理解

我们需要找到一个由最多两种不同字母组成的最长连续子串,并且可以通过最多 k 次修改来实现。这里的修改是指将某个位置的字符修改为任意字符。

2.2 数据结构选择

由于我们需要处理字符串,并且需要频繁地访问和修改字符串中的字符,因此选择字符串作为主要的数据结构是合适的。

三. 解题步骤

3.1 算法步骤

  1. 双层循环:我们需要尝试将字符串中的每个字符作为目标字符之一。由于字符串只包含大写字母,因此我们可以使用两个嵌套的循环来遍历所有可能的目标字符对(target1 和 target2)。
  2. 滑动窗口:使用滑动窗口技术来找到满足条件的最长子串。滑动窗口由两个指针 left 和 right 组成,表示当前窗口的左右边界。
  3. 修改次数管理:在滑动窗口的过程中,我们需要记录当前窗口内需要修改的字符数 changes。如果 changes 超过 k,则需要移动 left 指针,直到 changes 小于等于 k
  4. 更新最大长度:在每次移动 right 指针时,更新最大长度 maxLength

3.2 具体步骤

  1. 初始化:初始化 maxLength 为 0。

  2. 双层循环:外层循环遍历所有可能的目标字符 target1,内层循环遍历所有可能的目标字符 target2

  3. 滑动窗口

    • 初始化 left 和 right 指针为 0。

    • 初始化 changes 为 0。

    • 当 right 指针小于 n 时,执行以下操作:

      • 如果当前字符 inp.charAt(right) 既不是 target1 也不是 target2,则 changes 加 1。
      • 如果 changes 超过 k,则移动 left 指针,直到 changes 小于等于 k
      • 更新 maxLength 为当前窗口长度 right - left + 1 和 maxLength 中的较大值。
      • 移动 right 指针。
  4. 返回结果:返回 maxLength

3.3 复杂度分析

3.3.1 时间复杂度分析

  1. 双层循环

    • 外层循环遍历所有可能的目标字符 target1,从 'A' 到 'Z',共 26 次。
    • 内层循环遍历所有可能的目标字符 target2,从 'A' 到 'Z',共 26 次。
    • 因此,双层循环的总次数为 26 * 26 = 676 次。
  2. 滑动窗口

    • 在每次双层循环中,滑动窗口的 right 指针会遍历整个字符串 inp,长度为 n
    • 在每次滑动窗口的过程中,left 指针最多移动 n 次。
    • 因此,滑动窗口的总操作次数为 O(n)

综合以上分析,双层循环和滑动窗口的总时间复杂度为 O(26^2 * n),即 O(676 * n)。由于 676 是一个常数,因此实际的时间复杂度为 O(n)

3.3.2 空间复杂度分析

  1. 变量存储

    • 代码中使用了几个变量来存储指针、计数器和最大长度,这些变量的空间占用是常数级别的,即 O(1)
  2. 字符串

    • 输入字符串 inp 的空间占用为 O(n),其中 n 是字符串的长度。

综合以上分析,代码的空间复杂度为 O(n),主要由输入字符串的空间占用决定。

四. Code

public class Main {
    
    public static int solution(int n, int k, String inp) {
        int maxLength = 0;
        
        // 尝试将字符串中的每个字符作为目标字符之一
        for (char target1 = 'A'; target1 <= 'Z'; target1++) {
            for (char target2 = 'A'; target2 <= 'Z'; target2++) {
                if (target1 == target2) continue; // 跳过相同字符的情况
                
                int left = 0, right = 0;
                int changes = 0;
                
                // 使用滑动窗口来找到最大长度
                while (right < n) {
                    if (inp.charAt(right) != target1 && inp.charAt(right) != target2) {
                        changes++;
                    }
                    
                    // 如果修改次数超过k,移动左指针
                    while (changes > k) {
                        if (inp.charAt(left) != target1 && inp.charAt(left) != target2) {
                            changes--;
                        }
                        left++;
                    }
                    
                    // 更新最大长度
                    maxLength = Math.max(maxLength, right - left + 1);
                    right++;
                }
            }
        }
        
        return maxLength;
    }

    public static void main(String[] args) {
        // Add your test cases here
        System.out.println(solution(6, 1, "ABCBAD") == 5);
        System.out.println(solution(5, 1, "AEABD") == 4);
    }
}

五.总结

通过使用AI解决编程题目,开发者可以获得以下好处:

  • 提高效率:AI可以自动生成代码和测试用例,减少手动编写代码的时间。
  • 优化性能:AI提供代码优化建议,帮助开发者提升代码的性能。
  • 学习提升:AI提供解题思路和算法步骤的解析,帮助开发者学习新的编程技巧。