C++ 计算二进制字符串中选择三个索引的方式,这三个索引的相邻数字不能相同

C++ 计算二进制字符串中选择三个索引的方式,这三个索引的相邻数字不能相同

在这个问题中,我们将找出3个索引对的数量,使得在这个对中,任意相邻的索引都不具有相同的值。

我们可以通过检查每个3个索引对来获得输出,但这可能会耗费更多时间。解决这个问题的另一种方法是选择当前索引,并选择左右两个索引,这两个索引的值与当前索引的值不相同。这样,我们可以计算每个索引可以形成的总对数,并将它们相加以获得输出。

问题描述 - 给定一个二进制字符串bin_str,需要找到一对递增的3个索引的数量,使得相邻的索引不具有相同的值。

示例示例

输入

bin_str = "0101";

输出:

2

解释

我们可以取{0, 1, 2}和{1, 2, 3}索引对。所以,在010和101字符串中,任意两个相邻字符都不相同。

输入

bin_str = "110001";

输出

6

解释

我们可以取{0, 2, 5}, {0, 3, 5}, {0, 4, 5}, {1, 2, 5}, {1, 3, 5}, 和 {1, 4, 5}。

输入

bin_str = “11111”

输出

0

说明

由于字符串的所有字符都相同,它不包含任何所需的索引对。

方法1

在这个方法中,我们将使用三个嵌套循环来找到一对3个索引,使得相邻的索引不包含相同的值。我们将检查每一对是否符合问题陈述中的条件。

算法

  • 步骤1 - 将 ‘ans’ 初始化为0,以存储所需的对数。

  • 步骤2 - 使用第一个循环从第0个索引遍历到二进制字符串的长度-3个索引。

  • 步骤3 - 使用嵌套循环从(p + 1)索引遍历到二进制字符串的长度-2个索引。

  • 步骤4 - 使用另一个嵌套循环从(q + 1)索引遍历到二进制字符串的长度-1。

  • 步骤5 - 在嵌套循环中,如果p和q索引处的字符不相同,并且q和r索引处的字符不相同,将’ans’的值增加1。

  • 步骤6 - 返回’ans’的值。

示例

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

long long findIndexSelection(string bin_str) {
   int bin_len = bin_str.size();
   int ans = 0;

   // Creating the pair of 3 indexes
   for (int p = 0; p < bin_len - 2; p++) { 
      for (int q = p + 1; q < bin_len - 1; q++) {
         for (int r = q + 1; r < bin_len; r++) {

            // Check whether adjacent characters are the same or not
            if (bin_str[p] != bin_str[q] && bin_str[q] != bin_str[r]) {
              ans++;
            }
         }
      }
   }

   // Final output
   return ans;
}
int main() {
   string bin_str = "0101";
   cout << "The maximum number of ways to select indexes such that two adjacent indexes don't have the same character is " << findIndexSelection(bin_str) << endl;
   return 0;
}

输出

The maximum number of ways to select indexes such that two adjacent indexes don't have the same character is 2

时间复杂度 – O(NNN),因为我们使用了三个嵌套循环。

空间复杂度 – O(1),因为我们没有使用任何动态的空间。

方法2

如果我们想要使用当前索引来构造一对,我们需要取一个左索引和一个右索引,因为我们需要选择递增顺序的索引。因此,我们可以取左右两侧的所有索引,这些索引不包含与当前索引相同的字符。

使用当前索引可以构造的对数如下所示。

Pairs = (number of left indexes have dissimilar value) * (number of right indexes have dissimilar value)

之后,我们可以计算使用每个索引构建的成对项的总和。

算法

  • 步骤1 - 初始化’cnt1’和’cnt0’变量,以存储给定二进制字符串中0和1的计数。

  • 步骤2 - 遍历字符串并更新0和1的计数。

  • 步骤3 - 初始化’ans’为0,以存储总对数。

  • 步骤4 - 遍历字符串以找到总有效对数。

  • 步骤5 - 如果当前字符为’0’,将(ones * (cnt1 – ones))添加到’ans’中。我们计算左右两侧的1的乘积,形成类似101的一对。还要将’zeros’增加1。

  • 步骤6 - 如果当前字符为’1’,将(zeros * (cnt0 – zeros))添加到’ans’中。它形成像010的字符串。接下来,将’ones’增加1。

  • 步骤7 - 返回’ans’的值。

例子

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

long long findIndexSelection(string bin_str) {
   int bin_len = bin_str.size();
   // Counting the number of zeros and ones
   int cnt0 = 0, cnt1 = 0;

   // To store zeros and ones till ith index
   int zeros = 0, ones = 0;

   // Traverse the string to count 0's and 1's
   for (int p = 0; p < bin_len; p++) {
      if (bin_str[p] == '0') {
         cnt0++;
      } else {
         cnt1++;
      }
   }

   // To store the maximum number of pairs
   long long ans = 0;

   // Finding pairs
   for (int p = 0; p < bin_len; p++) {
      if (bin_str[p] == '0') {

         // Getting the number of pairs can be formed with a current index
         ans += (ones * (cnt1 - ones));

         // Increase zeros
         zeros++;
      } else {

         // Getting the number of pairs can be formed with a current index
         ans += (zeros * (cnt0 - zeros));
         ones++;
      }
   }
   return ans;
}
int main() {
   string bin_str = "1010";
   cout << "The maximum number of ways to select indexes such that two adjacent indexes don't have the same character is " << findIndexSelection(bin_str) << endl;
   return 0;
}

输出

The maximum number of ways to select indexes such that two adjacent indexes don't have the same character is 2

时间复杂度 – 遍历字符串为O(N)。

空间复杂度 – O(1),因为我们没有使用任何动态空间。

我们学习了解决问题的幼稚方法和优化方法。第一种方法具有较高的时间复杂度,不能用于大规模输入。第二种方法使用前缀1和0的概念来解决问题。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程