给定长度为N的二进制字符串S ,它由0s , 1s和“?”组成,其中“?”可以用0或1代替,任务是计算按非降序对字符串的每种可能排列进行排序所需的相邻字符的最小交换总和。由于答案可能非常大,请以模数10 9 +进行打印。 7 。
例子:
Input: S = “?0?”
Output: 3
Explanation:
Possible rearrangements of the given strings are {“101”, “100”, “000”, “001”}.
Minimum swaps to make “101” non-decreasing, i.e. “011” = 1.
Minimum swaps to make “100” non-decreasing, i.e. “001” = 2.
Minimum swaps to make “000” non-decreasing, i.e. “000” = 0.
Minimum swaps to make “001” non-decreasing, i.e. “001” = 0.
Therefore, total swaps required is 3.
Input: S = “1?00?”
Output: 17
方法:考虑以下字符串表示形式: <一些二进制字符串> 1 <一些数字为0且b为?的字符串>
- 对于右边的每个“ 0” ,对于每个问号生成的每个二进制字符串都有一个反转。因此,这里的反演为a * 2 b 。
- 对于问号,有 方法 选择,这样我有0个数字,并且每个数字都有i个取反。
- 共有
- 上面的表达式可以转换为b * 2 (b – 1) 。 如果没有“?”在字符串,值为0 。
- 那里的“ 1”总共算出了* 2 b + b * 2 (b – 1)的倒数。
- 对所有人 ”?”在“ 1”左侧,将上面的值乘以2,因为“?”将为每个计数的现有字符串生成两个新字符串。
- 遍历整个字符串,返回计数。
请按照以下步骤解决问题:
- 将变量计数初始化为0,以存储所有可能的字符串所需的总最小交换总数。
- 以相反的方式遍历二进制字符串。
- 对于字符串中的每个“ 1” ,计算0和2的计数的乘积(?的计数) ,即,将计数的值计算为a * 2 b + b * 2 (b – 1) 。
- 如果当前字符为“ 0” ,则 将计数增加0 s。
- 否则,将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
输出:
3
时间复杂度: O(N)
辅助空间: O(N)