📌  相关文章
📜  最小化相邻字符的交换以对给定二进制字符串的每个可能的重新排列进行排序

📅  最后修改于: 2021-09-17 07:42:03             🧑  作者: Mango

给定一个二进制字符串的长度N s包括0,1,和“?” ,哪里“?”可以替换为01 ,任务是计算以非递减顺序对字符串的每个可能排列进行排序所需的相邻字符的最小交换总和 由于答案可能非常大,将其打印为模10 9 + 7 .

例子:

方法:考虑下面的字符串表示: < Some binary 字符串 > 1

  • 对于其右侧的每个“0” ,为每个问号生成的每个二进制字符串都有一个反转。所以,这里的反转是a*2 b
  • 对于问号,有_{i}^{b}\textrm{C}          方法 选择,这样有i0并且对于它们中的每一个都有i 个反转。
  • 共有\sum_{i = 1}^{N}(_{i}^{b}\textrm{C})
  • 上面的表达式可以转换为b*2 (b – 1) 如果没有“?”在字符串,值为0
  • 在那里, “1”已被计算为总共a * 2 b + b * 2 (b – 1)反转。
  • 对全部 ”?”在“1”的左边将上面的值乘以2,因为一个“?”将为计算的每个现有字符串生成两个新字符串。
  • 遍历整个字符串,返回计数。

请按照以下步骤解决问题:

  • 将变量count初始化为0以存储所有可能字符串所需的总最小交换的总和。
  • 以相反的方式遍历二进制字符串。
    • 对于字符串中的每个“1” ,计算02计数的乘积(计数 ?) ,即计算计数的值为a * 2 b + b * 2 (b – 1)
    • 如果当前字符为“0” ,则 增加0秒的计数。
    • 否则,将count的值乘以2并重复上述过程。
  • 完成以上步骤后,打印count的值作为结果。

下面是上述方法的实现:

C++14
// C++ program for the above approach
#include
#define MOD  1000000007
using namespace std;
 
// Precalculate the values of power of 2
vector MEM = { 1, 2, 4, 8, 16, 32, 64,
                    128, 256, 512, 1024,
                    2048, 4096 };
 
// Function to calculate 2 ^ N % mod
int mod_pow2(int n)
{
    while (n >= MEM.size())
        MEM.push_back((MEM[-1] * 2) % MOD);
 
    return MEM[n];
}
 
// Function to find sum of inversions
int inversions(string bstr)
{
     
    // Initialise a list of 0s and ?s
    int total = 0, zeros = 0, questions = 0;
 
    // Traverse the string in the
    // reversed manner
    reverse(bstr.begin(),bstr.end());
 
    for(char x: bstr)
    {
        int q;
         
        // If the current character is 1
        if (x == '1')
        {
         
            // Effectively calculate a * b^(b-1)
            int z = zeros * mod_pow2(questions);
             
            if (questions == 0)
                q = 0;
            else
                q = questions * mod_pow2(
                    questions - 1);
             
            total = (total + z + q) % MOD;
        }
         
        // If the current character is 0
        else if (x == '0')
        {
            //Increment count of zeroes
            zeros += 1;
        }
        else
        {
             
            // Double count the zeroes
            total *= 2;
             
            // Find b * 2^(b-1)
            int z = zeros * mod_pow2(questions);
            if (questions == 0)
                q = 0;
            else
                q = questions * mod_pow2(
                    questions - 1);
             
            total = (total + z + q) % MOD;
             
            // Increment count of questions
            questions += 1;
        }
    }
     
    // Return the final count
    return total;
}
 
// Driver Code
int main()
{
     
    // Given string S
    string S = "?0?";
 
    // Function Call
    cout << inversions(S);
}
 
// This code is contributed by mohit kumar 29


Java
// Java program for the above approach
import java.io.*;
import java.util.*;
 
class GFG{
     
static int MOD = 1000000007;
 
static Integer array[] = { 1, 2, 4, 8, 16, 32, 64,
                           128, 256, 512, 1024,
                           2048, 4096 };
 
// Precalculate the values of power of 2
static Vector MEM = new Vector(
    Arrays.asList(array));
 
// Function to calculate 2 ^ N % mod
static int mod_pow2(int n)
{
    while (n >= MEM.size())
        MEM.add((MEM.get(
            MEM.size() - 1) * 2) % MOD);
     
    return MEM.get(n);
}
 
// Function to find sum of inversions
static int inversions(char[] bstr)
{
     
    // Initialise a list of 0s and ?s
    int total = 0, zeros = 0, questions = 0;
     
    // Traverse the string in the
    // reversed manner
    int j = bstr.length - 1;
    for(int i = 0; i < bstr.length / 2; i++)
    {
        char temp = bstr[i];
        bstr[i] = bstr[j];
        bstr[j] = temp;
        j--;
    }
     
    for(char x : bstr)
    {
        int q;
         
        // If the current character is 1
        if (x == '1')
        {
             
            // Effectively calculate a * b^(b-1)
            int z = zeros * mod_pow2(questions);
             
            if (questions == 0)
                q = 0;
            else
                q = questions * mod_pow2(
                    questions - 1);
             
            total = (total + z + q) % MOD;
        }
             
        // If the current character is 0
        else if (x == '0')
        {
             
            // Increment count of zeroes
            zeros += 1;
        }
        else
        {
             
            // Double count the zeroes
            total *= 2;
             
            // Find b * 2^(b-1)
            int z = zeros * mod_pow2(questions);
            if (questions == 0)
                q = 0;
            else
                q = questions * mod_pow2(
                    questions - 1);
             
            total = (total + z + q) % MOD;
             
            // Increment count of questions
            questions += 1;
        }
    }
     
    // Return the final count
    return total;
}
 
// Driver Code 
public static void main(String[] args)
{
     
    // Given string S
    char S[] = "?0?".toCharArray();
     
    // Function Call
    System.out.println(inversions(S));
}
}
 
// This code is contributed by divyeshrabadiya07


Python3
# Python3 program for the above approach
 
MOD = 10**9 + 7
 
# Precalculate the values of power of 2
MEM = [1, 2, 4, 8, 16, 32, 64, 128,
       256, 512, 1024, 2048, 4096]
 
# Function to calculate 2 ^ N % mod
def mod_pow2(n):
     
    while n >= len(MEM):
        MEM.append((MEM[-1] * 2) % MOD)
         
    return MEM[n]
 
# Function to find sum of inversions
def inversions(bstr):
 
    # Initialise a list of 0s and ?s
    total, zeros, questions = (0, )*3
 
    # Traverse the string in the
    # reversed manner
    for x in reversed(bstr):
 
        # If the current character is 1
        if x == '1':
 
            # Effectively calculate a * b^(b-1)
            z = zeros * mod_pow2(questions)
             
            if questions == 0:
                q = 0
            else:
                 q = questions * mod_pow2(questions - 1)
                  
            total = (total + z + q) % MOD
 
        # If the current character is 0
        elif x == '0':
         
            # Increment count of zeroes
            zeros += 1
 
        else:
         
            # Double count the zeroes
            total *= 2
 
            # Find b * 2^(b-1)
            z = zeros * mod_pow2(questions)
            if questions == 0:
                q = 0
            else:
                 q = questions * mod_pow2(questions - 1)
                  
            total = (total + z + q) % MOD
 
            # Increment count of questions
            questions += 1
     
    # Return the final count
    return total
 
# Driver Code
def main():
 
    # Given string S
    S = "?0?"
 
    # Function Call
    print(inversions(S))
 
 
if __name__ == "__main__":
    main()


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG {
 
  static int MOD = 1000000007;
 
  // Precalculate the values of power of 2
  static List MEM = new List(new int[] { 1, 2, 4, 8, 16, 32, 64,
                                                  128, 256, 512, 1024,
                                                  2048, 4096 });
 
  // Function to calculate 2 ^ N % mod
  static int mod_pow2(int n)
  {
    while (n >= MEM.Count)
      MEM.Add((MEM[MEM.Count - 1] * 2) % MOD);
 
    return MEM[n];
  }
 
  // Function to find sum of inversions
  static int inversions(char[] bstr)
  {
 
    // Initialise a list of 0s and ?s
    int total = 0, zeros = 0, questions = 0;
 
    // Traverse the string in the
    // reversed manner
    Array.Reverse(bstr);
 
    foreach(char x in bstr)
    {
      int q;
 
      // If the current character is 1
      if (x == '1')
      {
 
        // Effectively calculate a * b^(b-1)
        int z = zeros * mod_pow2(questions);
 
        if (questions == 0)
          q = 0;
        else
          q = questions * mod_pow2(
          questions - 1);
 
        total = (total + z + q) % MOD;
      }
 
      // If the current character is 0
      else if (x == '0')
      {
        // Increment count of zeroes
        zeros += 1;
      }
      else
      {
 
        // Double count the zeroes
        total *= 2;
 
        // Find b * 2^(b-1)
        int z = zeros * mod_pow2(questions);
        if (questions == 0)
          q = 0;
        else
          q = questions * mod_pow2(
          questions - 1);
 
        total = (total + z + q) % MOD;
 
        // Increment count of questions
        questions += 1;
      }
    }
 
    // Return the final count
    return total;
  }
 
  // Driver code
  static void Main()
  {
 
    // Given string S
    char[] S = "?0?".ToCharArray();
 
    // Function Call
    Console.WriteLine(inversions(S));
  }
}
 
// This code is contributed by divyesh072019


Javascript


输出:
3

时间复杂度: O(N)
辅助空间: O(N)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程