最小化比特替换次数,使01子串计数等于10子串计数


问题陈述 - 我们给定长度为 N 的二进制字符串。我们需要找到使二进制字符串平衡所需的最小翻转字符数。翻转字符意味着将 0 转换为 1,将 1 转换为 0。如果任何字符串包含相同数量的“01”和“10”对,我们可以说该字符串是平衡的二进制字符串。

示例

输入

str = "001010"

输出

0

解释 - 字符串包含 2 个“01”和“10”对。因此,我们不需要执行任何翻转操作。

输入

 str = ‘00001’

输出

1

解释 - 字符串包含 1 个“01”对,但不包含“10”对,因此我们需要执行 1 次翻转操作。

输入

 str = ‘1’

输出

0

解释 - 输入字符串已经平衡。

观察 - 我们可以注意到,如果字符串的第一个和最后一个字符相等,则二进制字符串始终包含相同数量的 01 和 10 对。

让我们看看下面的例子。

  • 1 - 字符串是平衡的,因为第一个和最后一个字符相同。

  • 0 - 平衡字符串。

  • 10 - 第一个和最后一个字符不同,因此字符串不平衡。

  • 101 - 平衡字符串。

  • 010 - 平衡字符串。

  • 1111 - 平衡字符串。

  • 01010 - 平衡字符串。

  • 0101 - 不平衡字符串。

方法 1

在这种方法中,我们将使用 map 数据结构来存储给定字符串的“01”和“10”对的总数。之后,我们可以取对数之间的差值以找到最小翻转次数。

算法

步骤 1 - 定义“count”map 来存储字符串和 int 的对。

步骤 2 - 此外,定义“temp”字符串来存储临时字符串。

步骤 3 - 遍历字符串直到倒数第二个索引。

步骤 4 - 在 temp 字符串中,存储从第 p 个索引开始长度为 2 的子字符串。

步骤 5 - 在 map 中增加“temp”字符串的计数。

步骤 6 - 取 count[01] 和 count[10] 之间的绝对差值并返回其值。

示例

#include <bits/stdc++.h>
using namespace std;

int totalReplacement(string alpha) {
    unordered_map<string, int> count;
    string temp;
    // count the number of occurrences of 01 and 10
    for (int p = 0; p < alpha.length() - 1; p++) {
        // substring of length 2 starting from index p
        temp = alpha.substr(p, 2);
        // Increase the count of temp by 1
        count[temp]++;
    }
    // return the absolute difference between the count of 01 and 10
    return abs(count["10"] - count["01"]);
}
int main() {
    string str = "001010";
    cout << "The total number of replacements required to make tota 01 equal to 10 is: " << totalReplacement(str) << endl;
    return 0;
}

输出

The total number of replacements required to make tota 01 equal to 10 is: 0

时间复杂度 - O(N),因为我们迭代字符串。

空间复杂度 - O(2) ~ O(1),因为我们使用 map。

方法 2

在这种方法中,我们将使用计数变量来存储字符串的 01 和 10 对的计数,而不是使用 map。它提高了代码的空间复杂度。

算法

步骤 1 - 定义“temp”字符串,并将“count01”和“count10”变量初始化为零。

步骤 2 - 使用 for 循环遍历字符串。

步骤 3 - 获取长度为 2 的子字符串。

步骤 4 - 如果 temp 等于“01”,则将“count01”的值增加 1。否则,将“count10”的值增加 1。

步骤 5 - 返回 count01 和 count10 之间的绝对差值。

示例

#include <bits/stdc++.h>
using namespace std;

int totalReplacement(string alpha) {
    string temp;
    int cnt01 = 0, cnt10 = 0;
    // count the number of occurrences of 01 and 10
    for (int p = 0; p < alpha.length() - 1; p++) {
        // substring of length 2 starting from index p
        temp = alpha.substr(p, 2);
        if (temp == "01") {
            cnt01++;
        } else {
            cnt10++;
        }
    }
    // return the absolute difference between the count of 01 and 10
    return abs(cnt01 - cnt10);
}
int main() {
    string str = "010101010101";
    cout << "The total number of replacements required to make tota 01 equal to 10 is: " << totalReplacement(str) << endl;
    return 0;
}

输出

The total number of replacements required to make tota 01 equal to 10 is: 1

时间复杂度 - O(N),因为我们迭代字符串。

空间复杂度 - O(1),因为我们使用常数空间。

对于任何给定的二进制字符串,我们将在输出中得到 0 或 1,因为根据 01 和 10 对的计数,我们需要使第一个和最后一个字符相同。

更新于: 2023年8月14日

104 次浏览

开启你的 职业生涯

通过完成课程获得认证

开始学习
广告