问题描述
小U拥有一个由0和1组成的字符串,她可以进行最多k次操作,每次操作可以交换相邻的两个字符。目标是通过这些操作,使得最终得到的字符串字典序最小。
例如,小U当前有一个字符串 01010,她最多可以进行 2 次相邻字符交换操作。通过这些操作,她可以将字符串调整为 00101,这是可以通过不超过2次操作得到的字典序最小的字符串。
现在,小U想知道,经过最多k次操作后,能够得到的字典序最小的字符串是什么。
测试样例
样例1:
输入:
n = 5, k = 2, s = "01010"
输出:'00101'
样例2:
输入:
n = 7, k = 3, s = "1101001"
输出:'0110101'
样例3:
输入:
n = 4, k = 1, s = "1001"
输出:'0101'
详细解答步骤
- 字符串转换:我们将输入的字符串
s转换为列表,因为在列表中交换字符比在字符串中直接交换要更高效。 - 外层循环遍历每个字符:从字符串的左端开始遍历。如果遇到
0,就跳过,因为它已经是字典序最优的位置了。 - 内层循环寻找
0:对于遇到的1,我们寻找后面出现的0,尽量将这个0交换到当前1的位置。每进行一次交换,k减少相应的交换次数。 - 停止条件:当没有足够的交换次数时,我们就停止操作。
测试样例分析
样例 1
输入:n = 5, k = 2, s = "01010"
- 初始状态:
01010 - 第 1 步:我们在索引 2(即 '1')后找到索引 3 的 '0',进行交换,得到
00110,剩余交换次数k = 1。 - 第 2 步:我们继续查找下一个 '0',在索引 4 找到 '0',进行交换,得到
00101,剩余交换次数k = 0。 - 最终结果:
00101
样例 2
输入:n = 7, k = 3, s = "1101001"
- 初始状态:
1101001 - 第 1 步:在索引 2 后找到 '0',交换得到
1011001,剩余k = 2。 - 第 2 步:继续查找,在索引 4 找到 '0',交换得到
0111001,剩余k = 1。 - 第 3 步:继续查找,在索引 5 找到 '0',交换得到
0110101,剩余k = 0。 - 最终结果:
0110101
样例 3
输入:n = 4, k = 1, s = "1001"
- 初始状态:
1001 - 第 1 步:我们在索引 2 后找到 '0',交换得到
0101,剩余k = 0。 - 最终结果:
0101
总结感悟
- 本题考察了贪心算法和字符交换的实现。通过每次尽量将
0向前移动,可以确保得到字典序最小的字符串。 - 操作次数
k是一个重要的限制条件,需要在交换过程中时刻关注剩余操作次数。 - 通过内外循环的组合,能有效地在给定的操作次数内将字符串调整到最优状态。