day02 字典序最小的01字符串(难)

101 阅读2分钟

问题描述

小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,是则进入下一步判断,反之break

4.对第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)