最小替换子串长度 | 字节青训营刷题

58 阅读3分钟

问题描述

小F得到了一个特殊的字符串,这个字符串只包含字符ASDF,其长度总是4的倍数。他的任务是通过尽可能少的替换,使得ASDF这四个字符在字符串中出现的频次相等。求出实现这一条件的最小子串长度。

总体思路

本题的核心目标是在给定的特殊字符串(只含字符 A、S、D、F 且长度为 4 的倍数)中,通过最少的替换操作让 A、S、D、F 这四个字符出现的频次相等,为此采用滑动窗口的方法来寻找满足条件的最小子串长度。

std::vector<int> count(4, 0);  // 0: 'A', 1: 'S', 2: 'D', 3: 'F'
for (char c : input) {
    if (c == 'A') count[0]++;
    else if (c == 'S') count[1]++;
    else if (c == 'D') count[2]++;
    else if (c == 'F') count[3]++;
}
  • 创建一个大小为 4 的整数向量 count,用于分别统计字符 ASDF 在输入字符串中出现的频次。初始时都设置为 0。
  • 通过遍历输入字符串 input,根据当前字符是 ASD 还是 F,相应地增加 count 向量中对应位置的计数。
std::vector<int> need(4, 0);
for (int i = 0; i < 4; ++i) {
    need[i] = std::max(0, count[i] - target);
}
  • 创建另一个大小为 4 的整数向量 need,用于表示每个字符需要替换的次数。
  • 通过遍历 count 向量,计算每个字符当前频次与目标频次的差值。如果差值大于 0,说明该字符出现次数过多,需要进行替换,将差值存入 need 向量对应位置;如果差值小于等于 0,则该位置设置为 0,表示不需要替换该字符。
if (need[0] == 0 && need[1] == 0 && need[2] == 0 && need[3] == 0) {
    return 0;
}
  • 在此处检查所有字符的 need 值是否都为 0,即是否所有字符的频次已经相等。如果是,说明不需要进行任何替换操作,直接返回 0,表示最小子串长度为 0。
int left = 0, right = 0;
int minLen = n;
std::vector<int> window(4, 0);

while (right < n) {
    // 扩展窗口
    char c = input[right];
    if (c == 'A') window[0]++;
    else if (c == 'S') window[1]++;
    else if (c == 'D') window[2]++;
    else if (c == 'F') window[3]++;
    right++;

    // 检查窗口是否满足条件
    while (window[0] >= need[0] && window[1] >= need[1] && window[2] >= need[2] && window[3] >= need[3]) {
        minLen = std::min(minLen, right - left);
        // 缩小窗口
        char d = input[left];
        if (d == 'A') window[0]--;
        else if (d == 'S') window[1]--;
        else if (d == 'D') window[2]--;
        else if (d == 'F') window[3]--;
        left++;
    }
}
  • 初始化滑动窗口的左右边界 left 和 right 都为 0,同时初始化最小子串长度 minLen 为输入字符串的长度 n,并创建一个大小为 4 的整数向量 window,用于统计当前滑动窗口内各个字符的频次。
  • 在外部的 while 循环中,不断扩展窗口(向右移动 right 指针),每次将新进入窗口的字符对应的 window 向量中的计数增加。
  • 内部的 while 循环用于检查当前窗口是否满足条件,即窗口内各个字符的频次是否都达到或超过了各自需要替换的次数(通过与 need 向量比较)。如果满足条件,就更新最小子串长度 minLen 为当前窗口长度(right - left)的最小值。然后尝试缩小窗口(向左移动 left 指针),将离开窗口的字符对应的 window 向量中的计数减少,继续寻找更小的满足条件的窗口。