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

48 阅读4分钟

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

例如,小U当前有一个字符串 01010,她最多可以进行 2 次相邻字符交换操作。

通过这些操作,她可以将字符串调整为 00101,这是可以通过不超过2次操作得到的字典序最小的字符串。 现在,小U想知道,经过最多k次操作后,能够得到的字典序最小的字符串是什么。

测试样例
输入:n = 5, k = 2, s = "01010" 输出:'00101'

解题思路

  1. 理解问题
  • 我们有一个由01组成的字符串。
  • 我们可以进行最多k次相邻字符的交换操作。
  • 目标是使得字符串的字典序最小。
  1. 数据结构选择
  • 使用字符串来表示当前的字符串状态。
  • 使用一个计数器来跟踪剩余的交换次数
  1. 算法步骤
  • 从字符串的第一个字符开始,尝试将当前字符与后面的字符进行交换,以使得字符串的字典序最小。
  • 每次交换后,更新剩余的交换次数。
  • 如果剩余的交换次数不足以进行进一步的交换,则停止操作。

代码框架

def solution(n: int, k: int, s: str) -> str:
    s = list(s)  # 将字符串转换为列表以便进行交换操作
    for i in range(n):
        if k == 0:
            break
        # 找到从i开始的最小字符及其位置
        min_char = s[i]
        min_index = i
        for j in range(i + 1, min(i + k + 1, n)):
            if s[j] < min_char:
                min_char = s[j]
                min_index = j
        # 将最小字符交换到当前位置
        while min_index > i:
            s[min_index], s[min_index - 1] = s[min_index - 1], s[min_index]
            min_index -= 1
            k -= 1
    return ''.join(s)

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

详细解释

循环查找最小字符
  for j in range(i + 1, min(i + k + 1, n)):
      if s[j] < min_char:
          min_char = s[j]
          min_index = j
  1. 初始条件
  • i 是当前需要放置最小字符的位置。
  • k 是剩余的交换次数。
  • n 是字符串的长度。
  • min_char 是当前位置 i 的字符。
  • min_index 是当前位置 i 的索引。
  1. 循环范围
  • for j in range(i + 1, min(i + k + 1, n)):
  • i + 1 表示从当前位置 i 的下一个位置开始。
  • min(i + k + 1, n) 表示循环的结束位置。这里使用了 min 函数来确保不会超出字符串的长度 n,同时限制在当前位置 i 之后的 k + 1 个字符范围内。
  1. 查找最小字符
  • if s[j] < min_char:
  • 如果当前字符 s[j] 小于 min_char,则更新 min_charmin_index
  • min_char = s[j]
  • 更新 min_char 为当前字符 s[j]
  • min_index = j
  • 更新 min_index 为当前字符 s[j] 的索引 j
交换字符并更新操作次数
   while min_index > i:
       s[min_index], s[min_index - 1] = s[min_index - 1], s[min_index]
       min_index -= 1
       k -= 1

假设当前字符串为 s = "01010"i = 1min_index = 3k = 2

  • 初始状态:s = "01010"min_index = 3i = 1k = 2
  • 第一次交换:s[3]s[2] 交换,字符串变为 "01001"min_index = 2k = 1
  • 第二次交换:s[2]s[1] 交换,字符串变为 "00101"min_index = 1k = 0
  • 此时,min_index 已经等于 i,循环结束,最小字符 0 已经移动到了当前位置 i

结语

本篇文章详细的介绍了一种解答方法,首先遍历字符串找到最小的字符集其位置,然后将最小字符串交换位置,最后返回结果。
需要注意的是k(剩余交换次数)的检查以及返回结果时s需要将列表转换成字符串。

希望此篇文章对您有所帮助