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

184 阅读4分钟

问题描述

小R得到了一个由大写字母组成的字符串,长度为 n。她可以对字符串中的字符进行修改,每次操作允许将某个位置的字符修改为任意字符。例如,字符串 ABC 的第一个字符 A 改为 B,则字符串变为 BBC。她最多可以进行 k 次这样的修改。 小R想知道,通过最多 k 次修改后,字符串中由最多两种不同字母组成的最长连续子串的长度是多少。

题目分析:给定一个由大写字母组成的字符串和一个整数k,我们需要找出通过最多k次修改后,字符串中由最多两种不同字母组成的最长连续子串的长度。

输入参数

  • n:字符串的长度。
  • k:允许的最大修改次数。
  • inp:输入的字符串。

输出参数

  • 返回一个整数,表示最长连续子串的长度。

算法思路

  1. 双重循环遍历所有字符对:由于我们需要考虑两种不同的字符,因此使用两层循环遍历所有可能的字符对(targetChar1targetChar2)。如果两个字符相同,则跳过,因为我们需要两种不同的字符。

  2. 维护窗口:使用两个指针leftright来维护一个窗口,这个窗口内的字符串将是我们考虑的子串。

  3. 计算修改次数:在right指针扩展窗口的过程中,如果当前字符既不是targetChar1也不是targetChar2,则增加修改次数changes

  4. 调整窗口以保持修改次数在限制内:如果修改次数超过了k,我们需要通过移动left指针来缩小窗口,直到修改次数不超过k。每次移动left指针时,如果该位置的字符既不是targetChar1也不是targetChar2,则减少修改次数。

  5. 更新最长子串长度:每次扩展right指针后,计算当前窗口的长度,并与之前找到的最长子串长度进行比较,更新最长子串长度。

  6. 返回结果:遍历完所有可能的字符对后,返回找到的最长子串长度。

代码实现

    
    public static int solution(int n, int k, String inp) {
        int maxLength = 0;
        for (char targetChar1 = 'A'; targetChar1 <= 'Z'; targetChar1++) {
            for (char targetChar2 = 'A'; targetChar2 <= 'Z'; targetChar2++) {
                if (targetChar1 == targetChar2) continue;
                int left = 0, right = 0, changes = 0;
                while (right < n) {
                    if (inp.charAt(right) != targetChar1 && inp.charAt(right) != targetChar2) {
                        changes++;
                    }
                    while (changes > k) {
                        if (inp.charAt(left) != targetChar1 && inp.charAt(left) != targetChar2) {
                            changes--;
                        }
                        left++;
                    }
                    maxLength = Math.max(maxLength, right - left + 1);
                    right++;
                }
            }
        }
        return maxLength;
    }

    public static void main(String[] args) {
        System.out.println(solution(6, 1, "ABCBAD") == 5);
        System.out.println(solution(5, 1, "AEABD") == 4);
        System.out.println(solution(8, 2, "AAAABBCD") == 8);
    }
}

代码中,我们首先定义了一个solution函数,它接受字符串长度n、修改次数k和字符串inp作为参数,并返回最长子串的长度。在函数内部,我们使用两层循环遍历所有可能的字符对,然后通过维护一个窗口来找到最长的子串。最后,我们在main函数中通过几个测试样例来验证算法的正确性。

注意事项

  • 代码中的maxLength变量用于存储找到的最长子串长度,初始值为0。
  • 在遍历字符对时,如果两个字符相同,则跳过,因为我们需要两种不同的字符。
  • 在扩展窗口时,如果当前字符既不是targetChar1也不是targetChar2,则增加修改次数。
  • 当修改次数超过k时,通过移动left指针来调整窗口,直到修改次数不超过k。
  • 每次扩展right指针后,都更新最长子串长度。

优化思考

当前算法的时间复杂度较高,因为它需要遍历所有可能的字符对,并且对于每一对字符,都需要遍历整个字符串。在实际应用中,可以考虑使用更高效的算法,例如动态规划或贪心算法,来减少计算量。此外,可以考虑使用哈希表来存储每个字符出现的次数,以快速判断当前窗口内的字符分布情况。