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

41 阅读3分钟

image.png

问题要求我们给定一个由 01 组成的字符串,最多可以进行 k 次相邻字符交换操作,目标是通过这些操作使得最终得到的字符串字典序最小。

关键思路:

  1. 字典序最小化:字典序最小的字符串意味着将字符串中尽可能多的 0 移动到字符串的前面,尽可能多的 1 移动到后面。所以,我们的目标是通过交换 01,尽量把 0 移到前面。
  2. 操作限制:每次我们只能交换相邻的字符,且每次操作会消耗一次机会(最多进行 k 次操作)。

解题步骤:

  1. 贪心策略:我们从左到右扫描字符串,每遇到一个 1,就尽量将其右边的 0 向前挪动。我们要寻找一个 0,并将它交换到当前 1 的前面。由于我们只有最多 k 次操作,因此需要优先交换最小的字符来实现字典序最小。

  2. 步骤细化

    • 从左到右扫描每一个位置,如果当前位置的字符是 1,我们尝试在当前位置 ii + k 之间(即当前 1 后面最多可以交换的范围)找到最小的字符 0,然后将其交换到当前位置。
    • 每次交换时要更新剩余的 k,确保不超过最大允许的操作次数。
  3. 优化策略:由于交换是局部的,且我们最多只能交换相邻的字符,因此我们可以通过一次次交换将较小的字符尽量交换到前面。

def solution(n: int, k: int, s: str) -> str:
    # 将字符串转换为列表以便进行交换操作
    s = list(s)
    
    for i in range(n):
        # 在当前位置 i 到 i + k 的范围内找到最小的字符
        min_index = i
        for j in range(i + 1, min(i + k + 1, n)):
            if s[j] < s[min_index]:
                min_index = j
        
        # 将找到的最小字符尽可能地向左移动
        while min_index > i and k > 0:
            # 交换相邻字符
            s[min_index], s[min_index - 1] = s[min_index - 1], s[min_index]
            min_index -= 1
            k -= 1
    
    # 将列表转换回字符串并返回
    return ''.join(s)

输入:`n = 7, k = 3, s = "1101001"`  
输出:`'0110101'`
  • 初始字符串:1101001,最多可以交换 3 次。

  • 在第一次操作时,我们可以交换第二个 1 和第三个 0,得到 1011001

  • 然后交换第三个 1 和第四个 0,得到 0111001

  • 最后交换第四个 1 和第五个 0,得到 0110101,这是字典序最小的字符串。

  • 结果为 '0110101'

复杂度分析:

  • 时间复杂度:最坏情况下,我们遍历每个字符并在范围 ii + k 内寻找最小字符,最内层的操作是交换,最坏情况下每个字符都要扫描 k 次。所以时间复杂度大约是 O(n * k),其中 n 是字符串长度。
  • 空间复杂度:由于我们将字符串转换为列表进行操作,额外的空间复杂度为 O(n)