最小替换子串长度
小F得到了一个特殊的字符串,这个字符串只包含字符A、S、D、F,其长度总是4的倍数。他的任务是通过尽可能少的替换,使得A、S、D、F这四个字符在字符串中出现的频次相等。求出实现这一条件的最小子串长度。
1.思路分析:
首先,由于字符串长度是 4 的倍数,要让 A、S、D、F 四个字符出现的频次相等,那就先算出每个字符的目标频次,即字符串总长度除以 4。接着统计当前字符串中各个字符的实际频次,然后算出每个字符实际频次与目标频次的差值。如果一开始所有字符的频次就已经相等了,那直接返回 0,表示不需要进行替换操作。若频次不相等,就采用滑动窗口的方法来解决问题。初始化滑动窗口的左边界 left 为 0,最小子串长度 min_length 先设为整个字符串的长度(后续会不断更新缩小),同时初始化一个字典 window_count 用于记录窗口内各个字符的出现频次。然后开始遍历字符串(通过 right 指针从左到右移动),每移动到一个新位置,就把对应字符在窗口内的频次加 1。接着检查当前窗口是否满足条件,也就是窗口内每个字符的频次都大于等于之前计算出的该字符需要调整的差值(通过 all 函数结合条件判断来检查)。如果满足条件,说明当前窗口有可能是符合要求的子串,就更新最小子串长度(取当前最小长度和当前窗口长度 right - left + 1 中的较小值),然后移动左指针,将左指针指向的字符在窗口内的频次减 1,相当于缩小窗口,继续往后寻找是否还有更短的满足条件的子串,直到遍历完整个字符串,最后返回的 min_length 就是满足条件的最小子串长度。
2.知识总结
频次统计与差值计算的字典推导式运用:代码中多次使用字典推导式来方便快捷地统计字符频次以及计算频次差值,能让代码在处理类似对多个元素进行相同逻辑的统计或计算操作时更加清晰可读,避免了写多个重复的 if-else 语句或者循环来分别处理不同元素的情况。
滑动窗口算法思想:通过维护一个窗口在字符串上滑动,动态地检查窗口内的数据是否满足特定条件,然后根据条件移动窗口(扩大或缩小)来寻找最优解。滑动窗口算法在处理很多涉及子串、子数组相关的最值、满足特定条件等问题时非常实用,能够降低时间复杂度,避免暴力解法中对所有可能子串或子数组的重复遍历。
利用 all 函数进行多条件判断:使用 all 函数结合生成器表达式(如 all(window_count[char] >= diff[char] for char in 'ASDF'))来一次性检查多个条件是否同时满足,相比于写多个 and 连接的条件判断语句更加简洁明了,而且代码的可扩展性更好,当需要增加或减少判断条件时,只需要修改生成器表达式中的内容即可。