- Data Structure
- Networking
- RDBMS
- Operating System
- Java
- MS Excel
- iOS
- HTML
- CSS
- Android
- Python
- C Programming
- C++
- C#
- MongoDB
- MySQL
- Javascript
- PHP
- Physics
- Chemistry
- Biology
- Mathematics
- English
- Economics
- Psychology
- Social Studies
- Fashion Studies
- Legal Studies
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Make Palindrome binary string with exactly βaβ 0s and βbβ 1s by replacing wild card '?'
When dealing with string manipulation problems, it's common to encounter scenarios where we need to transform a given string into a specific pattern or format. One such problem is making a palindrome binary string with a certain number of '0's and '1's while replacing wildcard characters represented by '?'.
In this article, we will explore an efficient algorithmic approach to solve this problem using C++. We'll discuss the problem statement, and its approach, and analyze the time and space complexity of the algorithm.
Problem Statement
Given a string consisting of '0's, '1's, and wildcard characters '?', we need to convert it into a palindromic binary string by replacing the '?' characters. The final palindrome string should contain exactly the 'a' number of '0's and 'b' number of '1's, where 'a' and 'b' are given integers. If it is not possible to form such a palindrome, we should return -1.
Approach
Initialize two pointers, 'left' and 'right,' pointing to the start and end of the string, respectively.
Use a for loop to count the occurrences of '0's and '1's. This step helps us determine how many '0's and '1's are already present in the string. Then, decrement the values of 'a' and 'b' accordingly.
Iterate over the string while 'left' is less than 'right':
If both 'S[left]' and 'S[right]' are '?' characters:
set 'S[left]' and 'S[right]' to '0' and decrement 'a' by 2, if the count of '0's (denoted by 'a') is greater than the count of '1's (denoted by 'b'),
otherwise, set 'S[left]' and 'S[right]' to '1' and decrement 'b' by 2.
If 'S[left]' is '?' and 'S[right]' is not '?':
set 'S[left]' to '0' and decrement 'a' by 1, if S[right] equals to '0'.
otherwise, set 'S[left]' to '1' and decrement 'b' by 1.
If 'S[right]' is '?' and 'S[left]' is not '?':
set 'S[right]' to '1' and decrement 'b' by 1, if S[left] equals to '1'.
otherwise, set 'S[right]' to '0' and decrement 'a' by 1.
If 'S[left]' is not '?' and 'S[right]' is not '?' but they are not equal, it is impossible to form a palindrome, so return β1.
Move the 'left' pointer to the right of the string and the 'right' pointer to the left.
For the strings of odd length and the middle element as'?':
If the count of '0's ('a') is greater than the count of '1's ('b'), set the middle element to '0' and decrement 'a' by 1.
Otherwise, set the middle character to '1' and decrement 'b' by 1.
Check if 'a' and 'b' are both zero. If they are, return the final palindromic binary string. Otherwise, return β1.
Example
Now, let us implement the above approach in different programming languages: C, C++, Java, and Python β
#include <stdio.h> #include <string.h> // Function to convert the string // to a binary palindromic string with 'a' 0's and 'b' 1's char* palindromicString(char S[], int a, int b){ int left = 0; int right = strlen(S) - 1; // count '0's and '1's in S for (int i = 0; i < strlen(S); i++) { if (S[i] == '0') { a--; } else if (S[i] == '1') { b--; } } // Replace '?' characters based on conditions while (left < right) { if (S[left] == '?' && S[right] == '?') { if (a > b) { S[left] = S[right] = '0'; a -= 2; } else { S[left] = S[right] = '1'; b -= 2; } } else if (S[left] == '?' && S[right] != '?') { if (S[right] == '0') { S[left] = S[right]; a--; } else { S[left] = S[right]; b--; } } else if (S[right] == '?' && S[left] != '?') { if (S[left] == '0') { S[right] = S[left]; a--; } else { S[right] = S[left]; b--; } } else if (S[left] != S[right]) { return "-1"; } left++; right--; } // If the string length is odd, handle the case of the middle character. if (strlen(S) % 2 != 0 && S[strlen(S) / 2] == '?') { if (a > b) { S[strlen(S) / 2] = '0'; a--; } else { S[strlen(S) / 2] = '1'; b--; } } // Return the palindromic binary string if 'a' and 'b' are both zero, else return -1. if (a == 0 && b == 0) { return S; } else { return "-1"; } } int main(){ char str[] = "01?1???"; int a = 4, b = 3; printf("%s\n", palindromicString(str, a, b)); return 0; }
Output
0101010
#include<iostream> #include<string> using namespace std; // Function to convert the string // to a binary palindromic string with 'a' 0's and 'b' 1's string palindromicString(string S, int a, int b) { int left = 0; int right = S.size() - 1; // count '0's and '1's in S for(auto s: S){ if(s=='0'){ a--; } else if(s=='1'){ b--; } } // Replace '?' characters based on conditions while (left < right) { if (S[left] == '?' && S[right] == '?') { if (a > b) { S[left] = S[right] = '0'; a -= 2; } else{ S[left] = S[right] = '1'; b -= 2; } } else if (S[left] == '?' && S[right] != '?') { if(S[right]=='0'){ S[left]=S[right]; a--; } else{ S[left]=S[right]; b--; } } else if (S[right] == '?' && S[left] != '?') { if(S[left]=='0'){ S[right]=S[left]; a--; } else{ S[right]=S[left]; b--; } } else if (S[left] != S[right]) { return "-1"; } left++; right--; } // If the string length is odd, handle the case of the middle character. if (S.size() % 2 != 0 && S[S.size() / 2] == '?') { if (a > b) { S[S.size() / 2] = '0'; a--; } else { S[S.size() / 2] = '1'; b--; } } // Return the palindromic binary string if 'a' and 'b' are both zero, else return -1. if (a == 0 && b == 0) { return S; } else { return "-1"; } } int main() { string str = "01?1???"; int a = 4, b = 3; cout << palindromicString(str, a, b) << endl; return 0; }
Output
0101010
public class PalindromicString { static String palindromicString(String str, int a, int b) { char[] S = str.toCharArray(); int left = 0; int right = S.length - 1; // count '0's and '1's in S for (char s : S) { if (s == '0') { a--; } else if (s == '1') { b--; } } // Replace '?' characters based on conditions while (left < right) { if (S[left] == '?' && S[right] == '?') { if (a > b) { S[left] = S[right] = '0'; a -= 2; } else { S[left] = S[right] = '1'; b -= 2; } } else if (S[left] == '?' && S[right] != '?') { if (S[right] == '0') { S[left] = S[right]; a--; } else { S[left] = S[right]; b--; } } else if (S[right] == '?' && S[left] != '?') { if (S[left] == '0') { S[right] = S[left]; a--; } else { S[right] = S[left]; b--; } } else if (S[left] != S[right]) { return "-1"; } left++; right--; } // If the string length is odd, handle the case of the middle character. if (S.length % 2 != 0 && S[S.length / 2] == '?') { if (a > b) { S[S.length / 2] = '0'; a--; } else { S[S.length / 2] = '1'; b--; } } // Return the palindromic binary string if 'a' and 'b' are both zero, else return -1. if (a == 0 && b == 0) { return new String(S); } else { return "-1"; } } public static void main(String[] args) { String str = "01?1???"; int a = 4, b = 3; System.out.println(palindromicString(str, a, b)); } }
Output
0101010
def palindromic_string(s, a, b): S = list(s) left = 0 right = len(S) - 1 # count '0's and '1's in S for char in S: if char == '0': a -= 1 elif char == '1': b -= 1 # Replace '?' characters based on conditions while left < right: if S[left] == '?' and S[right] == '?': if a > b: S[left] = S[right] = '0' a -= 2 else: S[left] = S[right] = '1' b -= 2 elif S[left] == '?' and S[right] != '?': if S[right] == '0': S[left] = S[right] a -= 1 else: S[left] = S[right] b -= 1 elif S[right] == '?' and S[left] != '?': if S[left] == '0': S[right] = S[left] a -= 1 else: S[right] = S[left] b -= 1 elif S[left] != S[right]: return "-1" left += 1 right -= 1 # If the string length is odd, handle the case of the middle character. if len(S) % 2 != 0 and S[len(S) // 2] == '?': if a > b: S[len(S) // 2] = '0' a -= 1 else: S[len(S) // 2] = '1' b -= 1 # Return the palindromic binary string if 'a' and 'b' are both zero, else return -1. if a == 0 and b == 0: return ''.join(S) else: return "-1" if __name__ == "__main__": s = "01?1???" a, b = 4, 3 print(palindromic_string(s, a, b))
Output
0101010
Complexity Analysis
Time Complexity β The algorithm performs a forward pass over the string to count the occurrences of '0's and '1's, which takes O(N) time, where N is the length of the string. Then, it iterates over the string from both ends, which takes O(N/2). Overall, the time complexity of the solution is O(N).
Space Complexity β Due to the necessity to store the input string and a few other variables that require constant space, the solution has an O(N) space complexity.
Test Case
Test case → "01?1???", a=4, b=3
The input string S is set as "01?1???" and a is set to 4, and b is set to 3.
The palindromicString function is called with the given parameters.
The function starts by initializing the left and right pointers to the beginning and end of the string S, respectively.
Iterating through each character in S to count the occurrences of '0' and '1' and decrement a and b accordingly, results into a=3 and b=1, since there is already one '0' and two '1's in the string.
The function enters a while loop that continues until the left pointer crosses the right pointer.
Inside the while loop, the function checks various conditions to replace '?' characters based on the counts of '0' and '1'.
In the first iteration, S[left] is '0' and S[right] is '?'. Since S[left] is '0', it replaces S[right] with '0' and decrements a by 1, so, now a=2.
The updated string becomes "01?1??0".
The left pointer is incremented, and the right pointer is decremented.
In the second iteration, S[left] is '1' and S[right] is '?'. Since S[left] is '1', it replaces S[right] with '1' and decrements b by 1, so, now b=1.
The updated string becomes "01?1?10".
The pointers are updated.
In the third iteration, S[left] is '?' and S[right] is '?'. Since a is greater than b, both '?' characters are replaced with '0', and a is decremented by 2, so now a=0.
The pointers are updated and overlap this time. So, the while loop discontinues and the string becomes "0101010".
The function checks the case of the middle character. Since the length is odd but the middle character is '1', it doesn't check the middle element condition.
Finally, the function checks if both a and b are zero. Since a is 0 and b is 0, the modified string "0101010" is returned.
The result is printed to the console, which is "0101010".
Conclusion
In this article, we examined an effective algorithm for reusing the wildcard character '?' to transform a given string into a palindrome. We can make sure the final string contains precisely the 'a' number of '0's and 'b' number of '1's by carefully changing the '?' characters based on particular conditions. We went over the stepβbyβstep algorithm, offered a C++, C, Java, and Python implementation, and examined the solution's time and space complexity.