字典序最小的01字符串| 豆包MarsCode AI 刷题

29 阅读3分钟

问题描述:

小U拥有一个由0和1组成的字符串,她可以进行最多k次操作,每次操作可以交换相邻的两个字符。目标是通过这些操作,使得最终得到的字符串字典序最小。

例如,小U当前有一个字符串 01010,她最多可以进行 2 次相邻字符交换操作。通过这些操作,她可以将字符串调整为 00101,这是可以通过不超过2次操作得到的字典序最小的字符串。

现在,小U想知道,经过最多k次操作后,能够得到的字典序最小的字符串是什么。

解题思路

问题理解

你有一个由0和1组成的字符串,并且可以进行最多k次相邻字符的交换操作。目标是使得最终得到的字符串字典序最小。

数据结构选择

由于字符串只包含0和1,并且我们需要频繁地进行字符交换操作,因此将字符串转换为列表是一个不错的选择。列表支持高效的元素交换操作。

算法步骤
  1. 转换字符串为列表:将输入的字符串转换为列表,以便进行交换操作。
  2. 遍历字符串:从左到右遍历字符串中的每个字符。
  3. 寻找最小字符:对于当前字符,找到它可以在k次操作内移动到的最前面的位置,并记录该位置。
  4. 交换字符:如果找到的位置在当前字符的右边,并且交换次数不超过k,则进行交换操作。
  5. 更新k值:每次交换操作后,减少k的值。
  6. 返回结果:将列表转换回字符串并返回。
关键点
  • 贪心策略:每次选择当前字符可以移动到的最前面的位置,这样可以保证字典序最小。
  • 边界条件:确保交换次数不超过k,并且在遍历过程中更新k的值。

代码

def solution(n: int, k: int, s: str) -> str:
    # 将字符串转换为列表,以便进行交换操作
    s_list = list(s)
    
    # 遍历字符串中的每个字符
    for i in range(n):
        # 找到当前字符可以移动到的最前面的位置
        min_index = i
        for j in range(i + 1, min(i + k + 1, n)):
            if s_list[j] < s_list[min_index]:
                min_index = j
        
        # 计算需要进行的交换次数
        swaps = min_index - i
        
        # 如果交换次数不超过 k,则进行交换
        if swaps <= k:
            # 将 s_list[min_index] 移动到 s_list[i] 的位置
            for j in range(min_index, i, -1):
                s_list[j], s_list[j - 1] = s_list[j - 1], s_list[j]
                k -= 1  # 每次交换减少一次操作次数
    
    # 将列表转换回字符串并返回
    return ''.join(s_list)

if __name__ == '__main__':
    print(solution(5, 2, "01010") == '00101')
    print(solution(7, 3, "1101001") == '0110101')
    print(solution(4, 1, "1001") == '0101')