通过替换通配符使回文二进制字符串恰好具有 0 和 b 1 吗?
给定一个包含N个字符的字符串S ,其中包含'?' , ' 0 ', 和' 1 ' 以及两个字符串a和b ,任务是通过替换 ' ? ' 带有 ' 0 ' 或 ' 1 '。
例子:
Input: S = “10?????1”, a = 4, b = 4
Output: 10100101
Explanation: The output string is a palindromic binary string with exactly 4 0’s and 4 1’s.
Input: S = “??????”, a = 5, b = 1
Output: -1
Explanation: There does not exist any palindromic string with exactly a 0’s and b 1’s.
方法:给定的问题可以通过使用以下观察来解决:
- 对于由N个字符组成的字符串S是回文, S[i] = S[Ni-1]必须对[0, N)范围内的i的所有值都成立。
- 如果S[i]和S[Ni-1]中只有一个等于 ' ? ',则必须替换为其他索引的对应字符。
- 如果S[i]和S[Ni-1]的值都是 ' ? ',最佳的选择是用所需计数更多的字符替换它们。
使用上述观察结果,请按照以下步骤解决问题:
- 遍历[0, N/2)范围内的字符串,对于只有S[i]和S[N – i – 1]之一等于 ' ? ',将其替换为对应的字符。
- 在上述操作之后,通过减去“ 0 ”和“ 1 ”的计数来更新a和b的值。使用 std::count函数可以轻松计算计数。
- 现在遍历[0, N/2)范围内的给定字符串,如果两者S[i] = ' ? ' 和S[Ni-1] = ' ? ',用所需计数更多的字符更新它们的值(即,如果a>b ,则使用' 0 ',否则使用' 1 ')。
- 在奇数字符串长度的情况下,中间字符为 ' ? ',用剩余计数的字符更新它。
- 如果a = 0且b = 0的值,则存储在S中的字符串是所需的字符串。否则,所需的字符串不存在,因此返回-1 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to convert the given string
// to a palindrome with a 0's and b 1's
string convertString(string S, int a, int b)
{
// Stores the size of the string
int N = S.size();
// Loop to iterate over the string
for (int i = 0; i < N / 2; ++i) {
// If one of S[i] or S[N-i-1] is
// equal to '?', replace it with
// corresponding character
if (S[i] == '?'
&& S[N - i - 1] != '?') {
S[i] = S[N - i - 1];
}
else if (S[i] != '?'
&& S[N - i - 1] == '?') {
S[N - i - 1] = S[i];
}
}
// Subtract the count of 0 from the
// required number of zeroes
a = a - count(S.begin(), S.end(), '0');
// Subtract the count of 1 from
// required number of ones
b = b - count(S.begin(), S.end(), '1');
// Traverse the string
for (int i = 0; i < N / 2; ++i) {
// If both S[i] and S[N-i-1] are '?'
if (S[i] == '?' && S[N - i - 1] == '?') {
// If a is greater than b
if (a > b) {
// Update S[i] and S[N-i-1] to '0'
S[i] = S[N - i - 1] = '0';
// Update the value of a
a -= 2;
}
else {
// Update S[i] and S[N-i-1] to '1'
S[i] = S[N - i - 1] = '1';
// Update the value of b
b -= 2;
}
}
}
// Case with middle character '?'
// in case of odd length string
if (S[N / 2] == '?') {
// If a is greater than b
if (a > b) {
// Update middle character
// with '0'
S[N / 2] = '0';
a--;
}
else {
// Update middle character
// by '1'
S[N / 2] = '1';
b--;
}
}
// Return Answer
if (a == 0 && b == 0) {
return S;
}
else {
return "-1";
}
}
// Driver Code
int main()
{
string S = "10?????1";
int a = 4, b = 4;
cout << convertString(S, a, b);
return 0;
}
Python3
# Python program for the above approach
# Function to convert the given string
# to a palindrome with a 0's and b 1's
def convertString(S, a, b):
print(S)
# Stores the size of the string
N = len(S)
# Loop to iterate over the string
for i in range(0, N // 2):
# If one of S[i] or S[N-i-1] is
# equal to '?', replace it with
# corresponding character
if (S[i] == '?' and S[N - i - 1] != '?'):
S[i] = S[N - i - 1]
elif (S[i] != '?' and S[N - i - 1] == '?'):
S[N - i - 1] = S[i]
# Subtract the count of 0 from the
# required number of zeroes
cnt_0 = 0
for i in range(0, N):
if (S[i] == '0'):
cnt_0 += 1
a = a - cnt_0
# Subtract the count of 1 from
# required number of ones
cnt_1 = 0
for i in range(0, N):
if (S[i] == '0'):
cnt_1 += 1
b = b - cnt_1
# Traverse the string
for i in range(0, N // 2):
# If both S[i] and S[N-i-1] are '?'
if (S[i] == '?' and S[N - i - 1] == '?'):
# If a is greater than b
if (a > b):
# Update S[i] and S[N-i-1] to '0'
S[i] = S[N - i - 1] = '0'
# Update the value of a
a -= 2
else:
# Update S[i] and S[N-i-1] to '1'
S[i] = S[N - i - 1] = '1'
# Update the value of b
b -= 2
# Case with middle character '?'
# in case of odd length string
if (S[N // 2] == '?'):
# If a is greater than b
if (a > b):
# Update middle character
# with '0'
S[N // 2] = '0'
a -= 1
else:
# Update middle character
# by '1'
S[N // 2] = '1'
b -= 1
# Return Answer
if (a == 0 and b == 0):
return S
else:
return "-1"
# Driver Code
S = "10?????1"
S = list(S)
a = 4
b = 4
print("".join(convertString(S, a, b)))
# This code is contributed by gfgking
C#
// C# program for the above approach
using System;
class GFG {
// Function to convert the given string
// to a palindrome with a 0's and b 1's
static string convertString(string S, int a, int b)
{
// Stores the size of the string
int N = S.Length;
char[] str = S.ToCharArray();
// Loop to iterate over the string
for (int i = 0; i < N / 2; ++i) {
// If one of S[i] or S[N-i-1] is
// equal to '?', replace it with
// corresponding character
if (str[i] == '?' && str[N - i - 1] != '?') {
str[i] = str[N - i - 1];
}
else if (str[i] != '?'
&& str[N - i - 1] == '?') {
str[N - i - 1] = str[i];
}
}
// Subtract the count of 0 from the
// required number of zeroes
int countA = 0, countB = 0;
for (int i = 0; i < str.Length; i++) {
if (str[i] == '0')
countA++;
else if (str[i] == '1')
countB++;
}
a = a - countA;
// Subtract the count of 1 from
// required number of ones
b = b - countB;
// Traverse the string
for (int i = 0; i < N / 2; ++i) {
// If both S[i] and S[N-i-1] are '?'
if (str[i] == '?' && str[N - i - 1] == '?') {
// If a is greater than b
if (a > b) {
// Update S[i] and S[N-i-1] to '0'
str[i] = '0';
str[N - i - 1] = '0';
// Update the value of a
a -= 2;
}
else {
// Update S[i] and S[N-i-1] to '1'
str[i] = '1';
str[N - i - 1] = '1';
// Update the value of b
b -= 2;
}
}
}
// Case with middle character '?'
// in case of odd length string
if (str[N / 2] == '?') {
// If a is greater than b
if (a > b) {
// Update middle character
// with '0'
str[N / 2] = '0';
a--;
}
else {
// Update middle character
// by '1'
str[N / 2] = '1';
b--;
}
}
// Return Answer
if (a == 0 && b == 0) {
return new String(str);
}
else {
return "-1";
}
}
// Driver Code
public static void Main()
{
string S = "10?????1";
int a = 4, b = 4;
Console.Write(convertString(S, a, b));
}
}
// This code is contributed by ukasp.
Javascript
输出:
10100101
时间复杂度: O(N)
辅助空间: O(1)