问题描述
小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) {
//记录前面有多少个1
int count = 0;
for(int i = 0; i < n; i++) {
//遇1记录并跳过找0;
if(s.charAt(i) == '1') {
count++;
continue;
}
//遇0则0往前移动k或者count个位置(哪个小取哪个)
else{
if(count!=0) {
if(count >= k) {
s = s.substring(0, i - k) + '0' + s.substring(i - k, i) + s.substring(i + 1);
k = 0;
break;
}
else{
//边界处理
if(i + 1 < s.length()){
s = s.substring(0, i - count) + '0' + s.substring(i - count, i) + s.substring(i + 1);
}
else{
s = s.substring(0, i - count) + '0' + s.substring(i - count, i);
}
//更新k
k-=count;
}
}
}
if(k == 0) {
break;
}
}
return s;
}
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"));
}
}
代码解释
这段代码实现了一个字符串操作的逻辑,目标是将字符串中的某些字符移动到前面,以满足特定的条件。以下是对代码的详细解释:
代码功能
该代码定义了一个 solution
方法,接收三个参数:
-
n
:字符串的长度。 -
k
:表示可以移动的“步数”。 -
s
:一个由字符'0'
和'1'
组成的字符串。
方法的目标是将字符串中的某些 '0'
向前移动,移动的步数由 k
决定,同时保证移动后的字符串满足特定的规则。
代码逻辑
-
变量初始化:
-
count
:用于记录当前已经遇到的'1'
的数量。
-
-
遍历字符串:
-
使用
for
循环逐个检查字符串中的每个字符。
-
-
处理逻辑:
-
遇到
'1'
:-
增加
count
的值,表示又遇到一个'1'
。 -
使用
continue
跳过当前循环,继续检查下一个字符。
-
-
遇到
'0'
:-
如果
count
不为零,说明前面有'1'
,需要将当前的'0'
向前移动。 -
移动逻辑:
-
如果
count
大于等于k
,说明可以将当前的'0'
向前移动k
个位置。-
使用字符串拼接的方式,将
'0'
插入到当前位置减去k
的位置。 -
将
k
设置为零,表示步数已经用完。 -
使用
break
跳出循环,因为步数已经用完,无需继续处理。
-
-
如果
count
小于k
,说明可以将'0'
向前移动到第一个'1'
的位置。-
同样使用字符串拼接的方式,将
'0'
插入到当前位置减去count
的位置。 -
更新
k
的值,减去已经使用的步数(即count
)。
-
-
边界处理:如果当前字符是字符串的最后一个字符,需要避免索引越界。
-
-
-
-
循环结束:
-
如果在遍历过程中
k
已经用完(即k == 0
),则直接退出循环。
-
-
返回结果:
-
返回处理后的字符串。
-
示例解释
代码中还包含一个 main
方法,用于测试 solution
方法的正确性。以下是测试用例的解释:
-
solution(5, 2, "01010")
:-
初始字符串:
"01010"
。 -
第一个
'0'
不需要移动。 -
第二个
'0'
可以向前移动 2 个位置,最终结果为"00101"
。
-
-
solution(7, 3, "1101001")
:-
初始字符串:
"1101001"
。 -
第一个
'0'
可以向前移动 3 个位置,最终结果为"0110101"
。
-
-
solution(4, 1, "1001")
:-
初始字符串:
"1001"
。 -
第一个
'0'
可以向前移动 1 个位置,最终结果为"0101"
。
-
注意事项
-
字符串操作效率:
-
代码中使用了多次字符串拼接(如
substring
和字符串拼接操作),这在 Java 中效率较低,尤其是对于较长的字符串。如果需要优化,可以考虑使用StringBuilder
。
-
-
边界条件处理:
-
代码中对边界条件(如字符串末尾)进行了处理,避免了索引越界的问题。
-
-
逻辑限制:
-
该代码假设输入的字符串只包含
'0'
和'1'
,且k
的值不会超过字符串长度。
-
总结来说,这段代码通过模拟字符移动的过程,实现了将字符串中的 '0'
向前移动的功能,同时考虑了移动步数的限制和边界条件。