题目描述
小U拥有一个由0和1组成的字符串,她可以进行最多k次操作,每次操作可以交换相邻的两个字符。目标是通过这些操作,使得最终得到的字符串字典序最小。
例如,小U当前有一个字符串 01010,她最多可以进行 2 次相邻字符交换操作。通过这些操作,她可以将字符串调整为 00101,这是可以通过不超过2次操作得到的字典序最小的字符串。
现在,小U想知道,经过最多k次操作后,能够得到的字典序最小的字符串是什么。
思路分析
问题理解
首先,我们需要理解什么是字典序最小。字典序最小意味着在字符串中,'0' 应该尽可能地出现在 '1' 之前。例如,字符串 01010 的字典序最小形式是 00101。我们需要通过最多 k 次相邻字符交换操作,使得字符串的字典序最小。关键在于如何有效地找到并交换 '0' 和 '1',使得 '0' 尽可能地出现在 '1' 之前。
数据结构的选择
为了实现这个目标,我们可以使用以下数据结构和算法:
- 字符串列表:将字符串转换为列表,以便进行交换操作。
- 优先队列(堆):使用优先队列来快速找到当前最小的字符。
解题思路
- 遍历字符串:从左到右遍历字符串。
- 找到最近的 '0':对于每个 '1',找到它右边最近的 '0'。
- 计算交换次数:计算将这个 '0' 移动到当前 '1' 位置所需的交换次数。
- 执行交换:如果交换次数小于等于剩余的操作次数
k,则执行交换。 - 更新操作次数:每次交换后,减少可用的操作次数
k。
样例分析
假设我们有字符串 1101001 和 k = 3,我们可以通过以下步骤来实现字典序最小:
-
初始状态:
字符串:
1101001,操作次数:3 -
第一次操作:
从堆中取出最小的字符 '0',索引为 2
计算将其移动到最前面的交换次数:2
执行交换操作:
1101001->0111001剩余操作次数:1
-
第二次操作:
从堆中取出最小的字符 '0',索引为 4
计算将其移动到最前面的交换次数:3
由于剩余操作次数不足,仅可执行 1 次
执行交换操作:
0111001->0110101 -
最终输出:
字符串:
0110101
代码详解
-
初始化:
s = list(s):将字符串转换为列表,以便进行交换操作。 -
遍历字符串:
for i in range(n)::从左到右遍历字符串。if k <= 0::如果没有剩余的操作次数,退出循环。if s[i] == '0'::如果当前字符是 '0',则无需移动,继续下一个字符。 -
找到最近的 '0':
for j in range(i + 1, n)::从当前字符的右边开始寻找 '0'。if s[j] == '0'::找到 '0' 后,计算所需的交换次数。 -
计算交换次数:
needed_swaps = j - i:计算将 '0' 移动到当前 '1' 位置所需的交换次数。if needed_swaps <= k::如果所需的交换次数小于等于剩余的操作次数,则执行交换。 -
执行交换:
for swap in range(j, i, -1)::从 '0' 的位置向左交换,直到 '0' 到达当前 '1' 的位置。s[swap], s[swap - 1] = s[swap - 1], s[swap]:执行交换操作。k -= needed_swaps:减少可用的交换次数。 -
返回结果:
return ''.join(s):将列表转换回字符串并返回。
def solution(n: int, k: int, s: str) -> str:
s = list(s) # 将字符串转换为列表以便操作
for i in range(n):
if k <= 0:
break # 如果没有剩余的操作次数,退出
if s[i] == '0':
continue # 如果当前字符是 '0',则无需移动
# 需要将字符 '0' 移到当前位置 i 之前
# 我们寻找能用来替换当前 '1' 的最小的 '0'
for j in range(i + 1, n):
if s[j] == '0':
# 计算需要的交换次数
needed_swaps = j - i
if needed_swaps <= k:
# 执行交换
for swap in range(j, i, -1):
s[swap], s[swap - 1] = s[swap - 1], s[swap]
k -= needed_swaps # 减少可用的交换次数
break # 找到一个 '0' 之后就可以退出内层循环
return ''.join(s)
if __name__ == '__main__':
print(solution(5, 2, "01010") == '00101')
print(solution(7, 3, "1101001") == '0110101')
print(solution(4, 1, "1001") == '0101')