菜鸟第一篇|字典序最小的01字符串|豆包MarsCode AI技术刷题

57 阅读3分钟

一·题目内容

小U拥有一个由0和1组成的字符串,她可以进行最多k次操作,每次操作可以交换相邻的两个字符。目标是通过这些操作,使得最终得到的字符串字典序最小。 例如,小U当前有一个字符串01010,她最多可以进行2次相邻字符交换操作。通过这些操作,她可以将字符串调整为00101,这是可以通过不超过2次操作得到的字典序最小的字符串。 现在,小U想知道,经过最多k次操作后,能够得到的字典序最小的字符串是什么。

测试样例

895906897b56e8b6fa6ca9d504b5db5.jpg

二·python代码

        def solution(n: int, k: int, s: str) -> str:
        # write code here
        s_list = list(s)
        for i in range(n):
            min_idx = i
            for j in range(i + 1, min(i + k + 1, n)):
                if s_list[j] < s_list[min_idx]:
                    min_idx = j
            for j in range(min_idx, i, -1):
                s_list[j], s_list[j - 1] = s_list[j - 1], s_list[j]
            k -= min_idx - i
            if k == 0:
                break
        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')

三·代码思路

  1. 初始化

    • 将输入字符串 s 转换为列表 s_list,以便可以进行元素交换操作。
  2. 外层循环

    • 使用 for i in range(n) 遍历字符串的每个位置 i
  3. 寻找最小值

    • 在当前位置 i 之后的 k 个字符范围内(即 i + 1 到 min(i + k + 1, n)),寻找最小的字符,并记录其索引 min_idx
  4. 交换字符

    • 从 min_idx 开始,逐步将字符向前交换,直到字符到达位1. - 置 i。这样可以将最小的字符移动到当前位置 i
  5. 更新剩余操作次数

    • 每次交换操作后,更新剩余的操作次数 k,减去实际交换的次数(即 min_idx - i)。
  6. 终止条件

    • 如果剩余操作次数 k 为 0,则终止循环,不再进行更多的交换操作。
  7. 返回结果

    • 将列表 s_list 转换回字符串并返回。
  8. 循环范围

    • for j in range(min_idx, i, -1):这个循环从 min_idx 开始,逐步递减到 i(不包括 i)。-1 表示每次递减 1。
  9. 交换操作

    • s_list[j], s_list[j - 1] = s_list[j - 1], s_list[j]:这行代码执行交换操作。具体来说,它将 s_list[j] 和 s_list[j - 1] 的值互换。

循环代码片段

for j in range(min_idx, i, -1):
    s_list[j], s_list[j - 1] = s_list[j - 1], s_list[j]

详细解释

  1. 循环范围

    • for j in range(min_idx, i, -1):这个循环从 min_idx 开始,逐步递减到 i(不包括 i)。-1 表示每次递减 1。
  2. 交换操作

    • s_list[j], s_list[j - 1] = s_list[j - 1], s_list[j]:这行代码执行交换操作。具体来说,它将 s_list[j]s_list[j - 1] 的值互换。

四·具体步骤

假设当前 i 为 0,min_idx 为 2,s_list 为 ['0', '1', '0', '1', '0']

  1. 初始状态

    • s_list = ['0', '1', '0', '1', '0']
    • i = 0
    • min_idx = 2
  2. 第一次交换

    • j = 2

      • 当前 s_list[2] 是 '0's_list[1] 是 '1'

      • 交换 s_list[2] 和 s_list[1]

              s_list[2], s_list[1] = s_list[1], s_list[2]
        
      • 交换后,s_list 变为 ['0', '0', '1', '1', '0']

  3. 第二次交换

    • j = 1

      • 当前 s_list[1] 是 '0's_list[0] 是 '0'

      • 交换 s_list[1] 和 s_list[0]

           s_list[1], s_list[0] = s_list[0], s_list[1]
        
      • 交换后,s_list 变为 ['0', '0', '1', '1', '0']

测试用例

在 if __name__ == '__main__': 部分,代码通过调用 solution 函数并打印结果来验证代码的正确性。每个测试用例的输出是 True 或 False,表示结果是否与预期一致。

五·总结

该代码的思路是通过贪心算法,每次在当前位置 i 之后的 k 个字符范围内寻找最小的字符,并将其交换到当前位置 i。通过这种方式,逐步构建出字典序最小的字符串。