AI刷题 41.最小替换子串长度 | 豆包MarsCode AI刷题

49 阅读3分钟

学习笔记:最小替换子串长度

问题背景

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

问题分析

  1. 标准频次:由于字符串的长度是4的倍数,每个字符的标准频次应该是字符串长度除以4。
  2. 字符计数:首先计算每个字符的实际频次,并与标准频次进行比较,找出哪些字符超过了标准频次,哪些字符不足标准频次。
  3. 滑动窗口:使用滑动窗口技术,找到一个最短的子串,使得在这个子串中替换掉一些字符后,可以使整个字符串中每个字符的频次达到标准频次。

解决方案

  1. 初始化

    • 计算每个字符的标准频次。
    • 创建一个字符计数字典,记录每个字符的标准频次。
    • 初始化左边界 left 和最小长度 min_length
  2. 更新字符计数

    • 遍历字符串,更新字符计数字典。
    • 如果所有字符的频次都达到了标准频次,直接返回0。
  3. 滑动窗口

    • 使用一个滑动窗口,从左到右遍历字符串。
    • 每次移动右边界,更新字符计数字典。
    • 检查当前窗口内的字符频次是否满足条件。
    • 如果满足条件,计算当前窗口的长度,并更新最小长度。
    • 移动左边界,缩小窗口,继续检查。
  4. 返回结果

    • 如果找到了满足条件的最短子串,返回其长度。
    • 如果没有找到,返回0。

代码实现

def solution(input_str):
    # 计算每个字符的标准数量
    standard = len(input_str) // 4
    # 创建字符计数字典
    char_count = {'A': standard, 'S': standard, 'D': standard, 'F': standard}
    
    # 初始化边界
    left = 0
    min_length = float('inf')
    
    # 计算初始字符计数
    for char in input_str:
        char_count[char] -= 1
    
    # 如果已经满足条件,直接返回0
    if char_count['A'] == 0 and char_count['S'] == 0 and char_count['D'] == 0 and char_count['F'] == 0:
        return 0

    # 更新字符计数
    for right, char in enumerate(input_str):
        char_count[char] += 1
        
        # 检查是否满足条件
        while left <= right and char_count['A'] >= 0 and char_count['S'] >= 0 and char_count['D'] >= 0 and char_count['F'] >= 0:
            current_length = right - left + 1
            if current_length < min_length:
                min_length = current_length

            # 移动左边界
            char_count[input_str[left]] -= 1
            left += 1
    
    return min_length if min_length != float('inf') else 0

详细解释

  1. 计算标准频次

    • standard = len(input_str) // 4 计算每个字符的标准频次。
  2. 初始化字符计数字典

    • char_count = {'A': standard, 'S': standard, 'D': standard, 'F': standard} 创建字符计数字典,记录每个字符的标准频次。
  3. 更新字符计数

    • 遍历字符串,更新字符计数字典 char_count[char] -= 1
    • 如果所有字符的频次都达到了标准频次,直接返回0。
  4. 滑动窗口

    • 使用一个滑动窗口,从左到右遍历字符串。
    • 每次移动右边界,更新字符计数字典 char_count[char] += 1
    • 检查当前窗口内的字符频次是否满足条件 char_count['A'] >= 0 and char_count['S'] >= 0 and char_count['D'] >= 0 and char_count['F'] >= 0
    • 如果满足条件,计算当前窗口的长度 current_length = right - left + 1,并更新最小长度 min_length
    • 移动左边界 char_count[input_str[left]] -= 1,缩小窗口,继续检查。
  5. 返回结果

    • 如果找到了满足条件的最短子串,返回其长度 min_length
    • 如果没有找到,返回0。

通过上述方法,我们可以有效地解决这个问题,并通过测试用例验证其正确性。