Bootstrap

【教3妹学编程-算法题】2914. 使二进制字符串变美丽的最少修改次数

烦死了
3妹:呜呜,烦死了, 脸上长了一个痘
2哥 : 不要在意这些细节嘛,不用管它,过两天自然不就好了。
3妹:切,你不懂,影响这两天的心情哇。
2哥 : 我看你是不急着找工作了啊, 工作那么辛苦,哪还有时间想这些啊。
3妹:说到找工作,我又要去刷题了。
2哥:我给你出一道关于美丽的题吧,让你的心情美丽美丽~

题目:

给你一个长度为偶数下标从 0 开始的二进制字符串 s 。

如果可以将一个字符串分割成一个或者更多满足以下条件的子字符串,那么我们称这个字符串是 美丽的 :

每个子字符串的长度都是 偶数 。
每个子字符串都 只 包含 1 或 只 包含 0 。
你可以将 s 中任一字符改成 0 或者 1 。

请你返回让字符串 s 美丽的 最少 字符修改次数。

示例 1:

输入:s = “1001”
输出:2
解释:我们将 s[1] 改为 1 ,且将 s[3] 改为 0 ,得到字符串 “1100” 。
字符串 “1100” 是美丽的,因为我们可以将它分割成 “11|00” 。
将字符串变美丽最少需要 2 次修改。
示例 2:

输入:s = “10”
输出:1
解释:我们将 s[1] 改为 1 ,得到字符串 “11” 。
字符串 “11” 是美丽的,因为它已经是美丽的。
将字符串变美丽最少需要 1 次修改。
示例 3:

输入:s = “0000”
输出:0
解释:不需要进行任何修改,字符串 “0000” 已经是美丽字符串。

提示:

2 <= s.length <= 10^5
s 的长度为偶数。
s[i] 要么是 ‘0’ ,要么是 ‘1’ 。

思路:

思考

1、压缩数据,列表每个元素都是连续0或1子串的长度。
2、对压缩列表相邻元素(子串长度)奇偶判断。

复杂度:
时间复杂度:
O(n),n为字符串s长度。
空间复杂度:
O(n),n为字符串s长度。

java代码:

class Solution {
    public int minChanges(String s) {
        // 1、压缩数据,列表每个元素都是连续0或1子串的长度
        List<Integer> cntList = new ArrayList<>();
        char preC = s.charAt(0);
        int cnt = 0;
        for (char c : s.toCharArray()) {
            // 和上一个字符比较,判断是否连续相同
            if (c == preC) {
                cnt++;
            } else {
                // 记录子串长度
                cntList.add(cnt);
                cnt = 1;
            }
            preC = c;
        }
        cntList.add(cnt);

        int minChangeCnt = 0;
        // 2、对压缩列表相邻元素(子串长度)奇偶判断
        for (int i = 0; i < cntList.size(); i++) {
            cnt = cntList.get(i);
            if (cnt % 2 == 0) {
                // 跳过偶数
                continue;
            }
            // 奇数,预取下一个
            int nextCnt = cntList.get(i + 1);
            if (nextCnt % 2 == 1) {
                // 下一个奇数,调整1个。例:{1,3}=>{2,2}
                minChangeCnt++;
                // 已调整,跳过下一个
                i++;
            } else {
                // 下一个是偶数,当前子串调整1个,下一个子串减1
                minChangeCnt++;
                cntList.set(i + 1, nextCnt - 1);
            }
        }
        return minChangeCnt;
    }
}
;