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

36 阅读2分钟

问题描述

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

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

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

问题解析

该问题需要通过最多 k 次相邻字符交换操作,使得给定的由 0 和 1 组成的字符串的字典序最小。字典序最小意味着字符串中的 0 应该尽可能靠前,1 应该尽可能靠后。

数据结构选择

由于字符串是不可变的,不方便字符的交换操作,故而我们可以将其转换为字符列表,以便进行交换操作。

算法步骤

  1. 初始化

    • 将字符串转换为字符列表`s_lis``。
    • 初始化一个计数器 change,用于记录已经进行的交换次数。
  2. 遍历字符列表

    • 从左到右遍历字符列表,寻找可以交换的 1 和 0
    • 如果找到 1 和 0 相邻的情况,进行交换,并使 change 计数+1。
    • 如果 change 达到 k,停止遍历。
  3. 返回结果

    • 将字符列表转换回字符串并返回。

关键点

1.交换条件:只有当 s_lis[i] == '1' 且 s_lis[i + 1] == '0' 时才进行交换。

2.交换次数限制:确保交换次数不超过 k

3.循环选择:由于条件为 change 达到 k时停止遍历,故采用while循环

代码

def solution(n: int, k: int, s: str) -> str:
    change = 0
    s_lis = list(s)
    counts = s_lis.count('1')
    if counts == 0:
        return s
    while change < k:
        for i in range(n-1):
            if s_lis[i] == '1' and s_lis[i + 1] == '0':
                s_lis[i], s_lis[i + 1] = '0', '1'
                change += 1
                break
         #如果字符序已为最小,无需继续交换,提前停止遍历
        if int(''.join(s_lis)) == int(counts*'1'):
            break
    return ''.join(s_lis)

运行上述代码,可以确定运行结果正确,测试样例全部通过。

总结

通过确定合适的交换条件并设置交换次数限制,可以逐步将字符串中的 1 向右移动,0 向左移动,从而得到字典序最小的字符串。