一·题目内容
小U拥有一个由0和1组成的字符串,她可以进行最多k次操作,每次操作可以交换相邻的两个字符。目标是通过这些操作,使得最终得到的字符串字典序最小。 例如,小U当前有一个字符串01010,她最多可以进行2次相邻字符交换操作。通过这些操作,她可以将字符串调整为00101,这是可以通过不超过2次操作得到的字典序最小的字符串。 现在,小U想知道,经过最多k次操作后,能够得到的字典序最小的字符串是什么。
测试样例
二·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')
三·代码思路
-
初始化:
- 将输入字符串
s转换为列表s_list,以便可以进行元素交换操作。
- 将输入字符串
-
外层循环:
- 使用
for i in range(n)遍历字符串的每个位置i。
- 使用
-
寻找最小值:
- 在当前位置
i之后的k个字符范围内(即i + 1到min(i + k + 1, n)),寻找最小的字符,并记录其索引min_idx。
- 在当前位置
-
交换字符:
- 从
min_idx开始,逐步将字符向前交换,直到字符到达位1. - 置i。这样可以将最小的字符移动到当前位置i。
- 从
-
更新剩余操作次数:
- 每次交换操作后,更新剩余的操作次数
k,减去实际交换的次数(即min_idx - i)。
- 每次交换操作后,更新剩余的操作次数
-
终止条件:
- 如果剩余操作次数
k为 0,则终止循环,不再进行更多的交换操作。
- 如果剩余操作次数
-
返回结果:
- 将列表
s_list转换回字符串并返回。
- 将列表
-
循环范围:
for j in range(min_idx, i, -1):这个循环从min_idx开始,逐步递减到i(不包括i)。-1表示每次递减 1。
-
交换操作:
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]
详细解释
-
循环范围:
for j in range(min_idx, i, -1):这个循环从min_idx开始,逐步递减到i(不包括i)。-1表示每次递减 1。
-
交换操作:
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']。
-
初始状态:
s_list = ['0', '1', '0', '1', '0']i = 0min_idx = 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']。
-
-
-
第二次交换:
-
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。通过这种方式,逐步构建出字典序最小的字符串。