问题描述 小U拥有一个由0和1组成的字符串,她可以进行最多k次操作,每次操作可以交换相邻的两个字符。目标是通过这些操作,使得最终得到的字符串字典序最小。
例如,小U当前有一个字符串 01010,她最多可以进行 2 次相邻字符交换操作。通过这些操作,她可以将字符串调整为 00101,这是可以通过不超过2次操作得到的字典序最小的字符串。
现在,小U想知道,经过最多k次操作后,能够得到的字典序最小的字符串是什么。 样例: 输入:n = 5, k = 2, s = "01010" 输出:'00101' 输入:n = 7, k = 3, s = "1101001" 输出:'0110101' 输入:n = 4, k = 1, s = "1001" 输出:'0101'
利用豆包MarsCode AI为我提供了解题思路: 问题理解 我们需要通过最多 k 次相邻字符交换操作,将一个由 0 和 1 组成的字符串调整为字典序最小的字符串。字典序最小意味着尽可能多的 0 应该在前面,1 在后面。 数据结构选择 由于我们需要频繁地进行字符交换操作,使用列表来存储字符串会更方便,因为列表支持高效的元素交换。 算法步骤 转换字符串为列表:将输入的字符串转换为列表,以便进行字符交换操作。 遍历字符串:从左到右遍历字符串,尝试将每个 0 尽可能地向左移动。 找到最近的 0:在当前位置 i 之后找到第一个 0。 交换操作:将找到的 0 向左移动,最多移动 min(k, j - i) 次,其中 j 是找到的 0 的位置。 更新操作次数:每次交换后,减少可用的操作次数 k。 继续遍历:移动到下一个位置,继续上述过程,直到遍历完整个字符串或操作次数用完。 返回结果:将最终的列表转换回字符串并返回。 关键点 贪心策略:每次尽量将 0 向左移动,以达到字典序最小的目标。 操作次数限制:每次交换操作后,需要更新剩余的操作次数 k,确保不超过限制。
最终编写的代码如下: `def solution(n: int, k: int, s: str) -> str: # 将字符串转为列表以便操作 s = list(s) i = 0
# 遍历字符串
while i < n and k > 0:
# 找到当前 `i` 后的第一个 `0`
j = i
while j < n and s[j] != '0':
j += 1
# 如果没有 `0`,直接退出
if j == n:
break
# 尽量将 `0` 移到左边,最多使用 `min(k, j - i)` 次交换
moves = min(k, j - i)
k -= moves
# 交换过程
while moves > 0:
s[j], s[j - 1] = s[j - 1], s[j]
j -= 1
moves -= 1
# 移动到下一位置
i += 1
# 返回最终字符串
return ''.join(s)
if name == 'main': print(solution(5, 2, "01010") == '00101') # True print(solution(7, 3, "1101001") == '0110101') # True print(solution(4, 1, "1001") == '0101') # True ` 利用豆包MarsCode AI帮我检查了代码: 代码分析 字符串转换为列表: s = list(s) 这一步是正确的,将字符串转换为列表以便进行交换操作。 遍历字符串: while i < n and k > 0: 这一步是正确的,确保在遍历字符串的同时操作次数 k 没有用完。 找到第一个 0: while j < n and s[j] != '0': 这一步是正确的,找到当前位置 i 后的第一个 0。 处理没有 0 的情况: if j == n: break 这一步是正确的,如果没有找到 0,直接退出循环。 交换操作: moves = min(k, j - i) 这一步是正确的,计算可以进行的交换次数。 k -= moves 这一步是正确的,更新剩余的操作次数。 while moves > 0: 这一步是正确的,进行交换操作。 s[j], s[j - 1] = s[j - 1], s[j] 这一步是正确的,进行相邻字符交换。 j -= 1 和 moves -= 1 这一步是正确的,更新交换位置和剩余交换次数。 移动到下一位置: i += 1 这一步是正确的,移动到下一个位置继续处理。 返回结果: return ''.join(s) 这一步是正确的,将列表转换回字符串并返回。