问题描述
小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'
代码实现
public class Main {
public static String solution(int n, int k, String s) {
// 将字符串转为字符数组
char[] chars = s.toCharArray();
// 遍历字符数组
for (int i = 0; i < n - 1; i++) { // 修复循环范围,确保 i + 1 不越界
if (k > 0) {
// 检查当前字符和下一个字符是否符合条件('1' 与 '0')
if (chars[i] == '1' && chars[i + 1] == '0') {
// 交换这两个字符
char tmp = chars[i + 1];
chars[i + 1] = chars[i];
chars[i] = tmp;
// 减少 k
k--;
// 如果交换后的前一个字符是 '1',则回退
if (i > 0 && chars[i - 1] == '1') {
i -= 2; // 回退2位,重新检查
}
}
} else {
break; // 如果 k 为 0,结束循环
}
}
// 返回修改后的字符数组转换为字符串
return new String(chars);
}
public static void main(String[] args) {
System.out.println(solution(5, 2, "01010").equals("00101"));
System.out.println(solution(7, 3, "1101001").equals("0110101"));
System.out.println(solution(4, 1, "1001").equals("0101"));
}
}
代码解析
1.将字符串s通过
s.toCharArray()转为字符数组2.遍历字符数组(因为要对第
i个元素和第i + 1个元素进行对比,所以i < n - 1)3.判断
k > 0,是则进入下一步判断,反之break4.对第
i个元素和第i + 1个元素进行对比,如果chars[i] == '1' && chars[i + 1] == '0'进行字符交换;然后进行k--操作并判断交换后当满足i > 0 && chars[i - 1] == '1'时,对i进行回退2步操作(不用担心出现i = -1,在进行下一次循环时i会自动进行自增操作)5.将修改后的字符数组转为字符串并返回
(刷题链接 字典序最小的01字符串 - MarsCode)