📌  相关文章
📜  使给定的二进制字符串交替所需的最小子串反转(1)

📅  最后修改于: 2023-12-03 14:49:58.838000             🧑  作者: Mango

使给定的二进制字符串交替所需的最小子串反转

介绍

在一段二进制字符串中,如果相邻的两个字符相同,则它们必须被交替(或称“翻转”),直到所有相邻的字符都不相同为止。本题中,我们要求找出最小的子串,使得经过翻转后,该子串内的所有相邻字符都不相同。

例如,对于二进制字符串0001100,可以将第2~3个字符翻转(变成01),从而得到0101100。若直接翻转前3个字符(变成1001100)则不会得到最小的子串。

思路

首先,我们可以将所有连续相同的字符缩成一个字符,以方便后面的处理。这样,我们只需要处理连续相异的字符即可。

假设某个连续相异的区间的长度为L,其中包含两种字符,分别是a和b。我们想让它们交替,即变成ababab…或bababa…的形式。为了尽可能少地翻转子串,我们只需要考虑将其翻转为ababab…的形式,再与bababa…比较即可。

具体来说,如果a出现的次数小于等于L/2,我们就将子串中的b全部变为a,否则将a全部变为b。这可以通过一次遍历字符串而得到。

复杂度分析

本题只需要一次线性扫描,时间复杂度为O(n)。空间复杂度为O(1)。

代码实现
def min_flips(s: str) -> int:
    # 将连续相同的字符缩成一个字符
    s = ''.join(c for i, c in enumerate(s) if i == 0 or s[i-1] != c)
    ans = 0
    for i in range(1, len(s), 2):
        ans += s[i] != s[i-1]
    return ans
int minFlips(string s) {
    int ans = 0;
    for (int i = 1; i < s.size(); i++) {
        if (s[i] == s[i-1]) {
            ans++;
            s[i] = s[i] == '0' ? '1' : '0';
        }
    }
    return ans;
}
public static int minFlips(String s) {
    int ans = 0;
    for (int i = 1; i < s.length(); i++) {
        if (s.charAt(i) == s.charAt(i-1)) {
            ans++;
            char c = s.charAt(i);
            s = s.substring(0, i) + (c == '0' ? '1' : '0') + s.substring(i+1);
        }
    }
    return ans;
}
function minFlips(s) {
    let ans = 0;
    s = [...s];
    for (let i = 1; i < s.length; i++) {
        if (s[i] === s[i-1]) {
            ans++;
            s[i] = s[i] === '0' ? '1' : '0';
        }
    }
    return ans;
}
def min_flips(s)
    ans = 0
    s = s.chars.chunk_while {|a, b| a == b}.map(&:first).join
    for i in 1...s.size
        if s[i] == s[i-1]
            ans += 1
            s[i] = s[i] == '0' ? '1' : '0'
        end
    end
    ans
end
func minFlips(s string) int {
    ans := 0
    tmp := []byte(s)
    for i := 1; i < len(tmp); i++ {
        if tmp[i] == tmp[i-1] {
            ans++
            if tmp[i] == '0' {
                tmp[i] = '1'
            } else {
                tmp[i] = '0'
            }
        }
    }
    return ans
}