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

60 阅读3分钟

“字符替换与最长字串问题”题目要求

一、问题描述

有一个由大写字母组成的字符串长度为n,现在可以对字符串中的字符进行修改:
每次允许将某个位置的字符修改为任意字符,比如说将字符串ABC第1个字符A改为B,则字符串变成BBC
这个操作最多可以执行k次,现在想知道修改之后,字符串中由最多两种字母组成的子串最大长度。

例如,给定歌单 [5, 3, 2, 1, 4],真实的播放顺序是 [5, 2, 4, 1, 3]

保证歌曲中的id两两不同。

输入格式

每个样例有两行;
第一行是整数 nkn 表示字符串长度,k 表示可以修改的最多次数;(3≤n≤2000, 1≤k≤100)
第二行是长度为 n 的字符串;

输出格式

每个样例一行,输出修改之后,由最多两种字母组成的子串最大长度;

二、测试样例

样例1:

输入:6 1 ABCBAD
输出:5

样例2:

输入:5 1 AEABD
输出:4

数据范围:

(3≤n≤2000, 1≤k≤100)
输出:4


三、题目解析

3.1代码思路

  1. 初始化队列:使用LinkedList实现Queue接口,并将所有歌曲ID放入队列中。
  2. 模拟播放过程:使用poll()方法从队列中取出并播放当前第一首歌。如果队列中还有歌曲,使用poll()方法取出当前第一首歌,并使用add()方法将其移到队列末尾。
  3. 记录播放顺序:将每次播放的歌曲ID记录到result数组中。
13. 定义 applyOperation 方法
    
    public static int solution(int n, int k, String inp) {
        int maxLength = 0;
        
        // 遍历所有可能的两种字符组合
        for (char c1 = 'A'; c1 <= 'Z'; c1++) {
            for (char c2 = 'A'; c2 <= 'Z'; c2++) {
                if (c1 == c2) continue; // 跳过相同的字符组合
                
                int left = 0, right = 0;
                int count1 = 0, count2 = 0; // 记录c1和c2的出现次数
                int changes = 0; // 记录当前窗口内的修改次数
                
                while (right < n) {
                    // 更新当前字符的计数
                    if (inp.charAt(right) == c1) count1++;
                    else if (inp.charAt(right) == c2) count2++;
                    else changes++; // 如果不是c1或c2,则需要修改
                    
                    // 如果修改次数超过k,移动左指针直到修改次数不超过k
                    while (changes > k) {
                        // 更新左指针字符的计数
                        if (inp.charAt(left) == c1) count1--;
                        else if (inp.charAt(left) == c2) count2--;
                        else changes--; // 如果不是c1或c2,则修改次数减少
                        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);
    }
}

四、知识总结

这段代码通过结合队列操作循环模拟的方式,较好地实现了自定义的播放机制,并利用队列数据结构的特点简化了复杂的逻辑。使用 Queue 数据结构来模拟播放列表,按照 FIFO 规则取出当前歌曲,实现顺序播放。利用队列的特性来处理“当前歌曲播放后,下一个歌曲移到末尾”的需求,这种操作非常适合队列。 使用 while 循环,通过 poll() 方法不断从队列中取出元素,直到队列为空。循环中的每一步都模拟了一个播放过程。这种模拟方式便于对流程进行控制,使得代码能按需改变播放顺序,例如将“跳过”的歌曲重新添加到队列末尾。用一个 result 数组来保存每首歌曲的播放顺序,确保了最终输出格式符合要求。每轮循环都通过 poll() 移除队首元素并条件性地重新插入元素,实现队列中元素的状态更新。这种状态更新思想适合处理类似调度、轮换等需求。