leetcode
leetcode 2451 ~ 2500
使二进制字符串变美丽的最少修改次数

使二进制字符串变美丽的最少修改次数

难度:

标签:

题目描述

You are given a 0-indexed binary string s having an even length.

A string is beautiful if it's possible to partition it into one or more substrings such that:

  • Each substring has an even length.
  • Each substring contains only 1's or only 0's.

You can change any character in s to 0 or 1.

Return the minimum number of changes required to make the string s beautiful.

 

Example 1:

Input: s = "1001"
Output: 2
Explanation: We change s[1] to 1 and s[3] to 0 to get string "1100".
It can be seen that the string "1100" is beautiful because we can partition it into "11|00".
It can be proven that 2 is the minimum number of changes needed to make the string beautiful.

Example 2:

Input: s = "10"
Output: 1
Explanation: We change s[1] to 1 to get string "11".
It can be seen that the string "11" is beautiful because we can partition it into "11".
It can be proven that 1 is the minimum number of changes needed to make the string beautiful.

Example 3:

Input: s = "0000"
Output: 0
Explanation: We don't need to make any changes as the string "0000" is beautiful already.

 

Constraints:

  • 2 <= s.length <= 105
  • s has an even length.
  • s[i] is either '0' or '1'.

代码结果

运行时间: 38 ms, 内存: 16.2 MB


/*
 * 思路:
 * 使用Java Stream API处理字符串,
 * 将字符串按每两个字符分组,然后检查这些分组中是否有相同字符。
 * 如果有则需要修改字符,统计修改次数。
 */
import java.util.stream.IntStream;

public class Solution {
    public int minChangesToMakeBeautiful(String s) {
        return (int) IntStream.range(0, s.length() / 2)
                .filter(i -> s.charAt(2 * i) == s.charAt(2 * i + 1))
                .count();
    }
}

解释

方法:

该题解的核心思路是检查字符串中相邻的字符是否相同。由于要求每个美丽子字符串只包含相同的字符且长度是偶数,我们可以将字符串视为由多个两个字符组成的子串来检查。对于每一个从索引1开始的奇数索引,如果它与前一个字符(偶数索引)不同,那么至少需要更改其中一个字符来确保这两个字符相同,从而使得从这个偶数索引开始的两个字符长的子串成为美丽的。通过这种方式,我们可以计算出整个字符串中需要修改的最小字符数,从而使整个字符串变为美丽的。

时间复杂度:

O(n)

空间复杂度:

O(1)

代码细节讲解

🦆
为什么选择从索引1开始,并且每隔一个元素进行检查,这种方法有什么特别的原因吗?
选择从索引1开始,并每隔一个元素进行检查(即检查所有奇数索引),是因为我们的目标是确保每两个相邻的字符组成的子串都只包含相同的字符。在二进制字符串中,每两个字符可以形成一个长度为2的子串,对于从索引0开始的偶数索引和其后的奇数索引(如0和1,2和3)这种配对方式,需要检查这两个字符是否相同。通过这种方式,我们能够确保所有的字符对都满足条件,从而使整个字符串变得美丽。
🦆
在这种解法中,如果遇到连续的奇数个相同字符如何处理?例如字符串 '111' 应该如何修改以满足题目要求?
在提出的解法中,我们是按每两个字符为一组进行检查和修改的。对于如 '111' 这样的字符串,我们按照索引检查(0和1,1和2),首先检查0和1时发现它们相同,不需要修改。然后检查1和2也发现它们相同,不需要修改。然而,根据题目要求,每个子字符串的长度必须是偶数,所以不能有长度为3的子字符串。在这种情况下,可以选择修改任何一个字符(比如中间的字符1改为0),使得字符串分割成两个长度为2的子字符串(如'10'和'01'),这样的修改次数最少。
🦆
解法中只考虑每两个相邻字符是否相同,那么整个字符串的长度是否一定会是偶数,如果是奇数长度的字符串该如何处理?
题目已明确指出给定的二进制字符串长度为偶数,因此在这种情况下我们不需要考虑字符串长度为奇数的情况。如果在其他情况下遇到奇数长度的字符串,我们需要在设计算法时考虑如何处理最后一个无法配对的字符。可能的处理方法包括增加一个字符使其长度变为偶数,或者在某个位置上做出修改,使得所有子字符串的长度都为偶数。

相关问题