问题描述:
小U拥有一个由0和1组成的字符串,她可以进行最多k次操作,每次操作可以交换相邻的两个字符。目标是通过这些操作,使得最终得到的字符串字典序最小。
例如,小U当前有一个字符串 01010,她最多可以进行 2 次相邻字符交换操作。通过这些操作,她可以将字符串调整为 00101,这是可以通过不超过2次操作得到的字典序最小的字符串。
现在,小U想知道,经过最多k次操作后,能够得到的字典序最小的字符串是什么。
解题思路
问题理解
你有一个由0和1组成的字符串,并且可以进行最多k次相邻字符的交换操作。目标是使得最终得到的字符串字典序最小。
数据结构选择
由于字符串只包含0和1,并且我们需要频繁地进行字符交换操作,因此将字符串转换为列表是一个不错的选择。列表支持高效的元素交换操作。
算法步骤
- 转换字符串为列表:将输入的字符串转换为列表,以便进行交换操作。
- 遍历字符串:从左到右遍历字符串中的每个字符。
- 寻找最小字符:对于当前字符,找到它可以在k次操作内移动到的最前面的位置,并记录该位置。
- 交换字符:如果找到的位置在当前字符的右边,并且交换次数不超过k,则进行交换操作。
- 更新k值:每次交换操作后,减少k的值。
- 返回结果:将列表转换回字符串并返回。
关键点
- 贪心策略:每次选择当前字符可以移动到的最前面的位置,这样可以保证字典序最小。
- 边界条件:确保交换次数不超过k,并且在遍历过程中更新k的值。
代码
def solution(n: int, k: int, s: str) -> str:
# 将字符串转换为列表,以便进行交换操作
s_list = list(s)
# 遍历字符串中的每个字符
for i in range(n):
# 找到当前字符可以移动到的最前面的位置
min_index = i
for j in range(i + 1, min(i + k + 1, n)):
if s_list[j] < s_list[min_index]:
min_index = j
# 计算需要进行的交换次数
swaps = min_index - i
# 如果交换次数不超过 k,则进行交换
if swaps <= k:
# 将 s_list[min_index] 移动到 s_list[i] 的位置
for j in range(min_index, i, -1):
s_list[j], s_list[j - 1] = s_list[j - 1], s_list[j]
k -= 1 # 每次交换减少一次操作次数
# 将列表转换回字符串并返回
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')