
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Maximize Value of Binary String in K Steps Using XOR
In this problem, we will maximize the value of the binary string by performing K XOR operations of substrings of the given binary string.
To maximize any binary string, we should maximize the substring starting from the leftmost zero. For example, to maximize the ?11001' string, we need to choose another substring in such a way that we can maximize the ?001' substring.
Problem Statement
We have given a binary string named bin_str containing N characters. We have to maximize the value of the binary string in K operations by taking the XOR operation of any two substrings. It is given that substrings can be the same, intersecting or non-intersecting.
Sample Examples
Input
bin_str = "1101"; K = 1;
Output
1111
Explanation
We can take 10 and 1101 substrings, and when we perform XOR of both, we get the 1111 maximum string.
Input
bin_str = "110101"; K = 2
Output
111110
Explanation
In the first operation, we can take 110101 and 1010 substrings. Whesubstringrm XOR operation of both strings, we get 111111 binary string.
In the second operation, we can take 111111 and 1 substring, and when we perform the XOR operation of both, we get 111110, the maximum string we can get.
Input
bin_str = "01"; K = 1;
Output
1
Explanation
Take 01 and 0 substrings to get 1.
Approach 1
In this approach, we will take a substring from the leftmost 0 to the end and find another substring of the string to get the maximum binary string value.
For example, the binary string is 1110010101. To maximize the binary string, we need to maximize the 0010101 substrings. So, we will take the binary string itself as one substring and another string of the same length, ?0010101,' to maximize the binary string.
Algorithm
Step 1 ? Execute the maxValUtil() function for K times, and update the binary string with its returned value.
Step 2 ? In the maxValUtil() function, Initialize the ?leftZero' with -1 to store the index of the leftmost zero, ?cnt0' and ?cnt1' with 0 to store the count of 0 and 1 in the binary string, respectively.
Step 3 ? Traverse the string, and if the current character is ?1', increment the ?cnt1' by 1. Otherwise, if ?leftZero' is -1, update its value with the current index and increment the ?cnt0' value.
Step 4 ? If ?cnt1' and ?len' is equal, take the XOR of a binary string with ?1' and return its value.
Step 4.1 ? Take the length of both strings in the getXOR() function. If both strings are not of the same length, add the zeros to the string with the smallest length by executing the addZeros() function.
Step 4.1.1 ? In the addZero() function, append the required zeros at the start of the string.
Step 4.2 ? Initialize the ?XOR" string to store the result after performing the XOR operation of both strings.
Step 4.3 ? Traverse both strings and if the character at the pth index in both strings is the same, append ?0' to the XOR string. Otherwise, append ?1' to the XOR string.
Step 4.4 ? Return the XOR string.
Step 5 ? In the maxValUtil() function, if ?cnt0' is equal to the binary string's length, return ?0'.
Step 6 ? Initialize the ?rightStr' string with the substring starting from the ?leftZero' index using the substr() method. Also, initialize the ?size' with the ?rightStr' string's size, temp with the ?rightStr' string, ?maxRes', ?temp1', and ?temp2' with an empty string.
Step 7 ? Start traversing the binary string. If the index is less than the ?size' variable's value, append a character to the ?temp1' string.
Step 8 ? Else, Get the XOR of the ?temp' and ?temp1' strings. If the XOR value exceeds the ?maxRes' string's value, update the ?maxRes' with ?res' and ?temp2' with ?temp1'. Also, remove the first character from the ?temp1' string and append the current character at last.
Here, we find the ?temp2' substring such that the XOR of ?temp1' and ?temp2' becomes maximum to maximize the binary string.
Step 9 ? Handle the last case in which we take XOR of temp1 string with rightStr string.
SStep 10 ? Next, take the XOR of the binary string and temp2 string, and store the result in the answer.
Step 11 ? Return the ?answer' string after removing the leading zeros.
Example
Following are the Programs to the above algorithm
#include <stdio.h> #include <string.h> #include <stdlib.h> // Added for dynamic memory allocation // Function to add 'n' zeros to the beginning of a string void addNZero(char *substr, int n) { int i; // Shift existing characters to the right to make space for zeros for (i = strlen(substr); i >= 0; i--) { substr[i + n] = substr[i]; } // Add 'n' zeros at the beginning for (i = 0; i < n; i++) { substr[i] = '0'; } } // Function to perform XOR of two strings void getXOR(char *temp1, char *temp2, char *result) { int len1 = strlen(temp1); int len2 = strlen(temp2); int len = len1 > len2 ? len1 : len2; // Maximum length int i; // Make both strings of equal length by adding leading zeros if (len1 > len2) { addNZero(temp2, len1 - len2); } else if (len2 > len1) { addNZero(temp1, len2 - len1); } // Compute XOR for (i = 0; i < len; i++) { if (temp1[i] == temp2[i]) { result[i] = '0'; } else { result[i] = '1'; } } // Null-terminate the result string result[len] = '\0'; } // Function to find the maximum value of a binary string after K XOR operations void findMaxValue(char *bin_str, int K) { int len = strlen(bin_str); int leftZero = -1, cnt0 = 0, cnt1 = 0; char *rightStr, *temp, *maxRes, *temp1, *temp2; int size; // Calculate the number of 0's and 1's in the binary string for (int p = 0; p < len; p++) { if (bin_str[p] == '1') { cnt1++; } else { if (leftZero == -1) { leftZero = p; } cnt0++; } } // Case 1 - When the string contains all 1's if (cnt1 == len) { char one[] = "1"; getXOR(bin_str, one, bin_str); return; } // Case 2 - When the string contains all zeros if (cnt0 == len) { printf("0\n"); return; } // Take the substring starting from the leftmost '0' to maximize it rightStr = bin_str + leftZero; size = len - leftZero; temp = rightStr; maxRes = (char *)malloc((len + 1) * sizeof(char)); // Allocate memory for maxRes temp1 = (char *)malloc((len + 1) * sizeof(char)); // Allocate memory for temp1 temp2 = (char *)malloc((len + 1) * sizeof(char)); // Allocate memory for temp2 // Initialize memory to avoid undefined behavior memset(maxRes, 0, (len + 1) * sizeof(char)); memset(temp1, 0, (len + 1) * sizeof(char)); memset(temp2, 0, (len + 1) * sizeof(char)); // Choosing the second string for (int q = 0; q < len; q++) { if (q < size) { temp1[q] = bin_str[q]; } else { // If temp1 gives the maximum XOR result, choose it as the second string char res[len + 1]; getXOR(temp, temp1, res); if (strcmp(res, maxRes) > 0) { strcpy(maxRes, res); strcpy(temp2, temp1); } // Update temp1 string for (int i = 0; i < size - 1; i++) { temp1[i] = temp1[i + 1]; } temp1[size - 1] = bin_str[q]; } } // Handling the last case char res[len + 1]; getXOR(temp1, temp, res); if (strcmp(res, maxRes) > 0) { strcpy(maxRes, res); strcpy(temp2, rightStr); } // Take the XOR of the original string and the second string getXOR(bin_str, temp2, bin_str); // Remove leading zeros leftZero = -1; for (int p = 0; p < len; p++) { if (bin_str[p] != '0') { leftZero = p; break; } } if (leftZero == -1) { printf("0\n"); } else { printf("%s\n", bin_str + leftZero); } // Free dynamically allocated memory free(maxRes); free(temp1); free(temp2); } int main() { char bin_str[] = "1101"; int K = 1; printf("The maximum value of the string after performing 1 XOR operations is - "); findMaxValue(bin_str, K); return 0; }
Output
The maximum value of the string after performing 1 XOR operations is - 1111
#include <bits/stdc++.h> using namespace std; void addNZero(string &substr, int n) { // Adding the initial '0' to the string to make its length the same as the other sub string for (int p = 0; p < n; p++) { substr = "0" + substr; } } // Finding XOR of two strings string getXOR(string temp1, string temp2) { // Get string sizes int temp1_len = temp1.length(); int temp2_len = temp2.length(); // Append zeros to the smaller string if (temp1_len > temp2_len) { addNZero(temp2, temp1_len - temp2_len); } else if (temp2_len > temp1_len) { addNZero(temp1, temp2_len - temp1_len); } // Final string length int len = max(temp1_len, temp2_len); // To store the resultant XOR string XOR = ""; // Take XOR of both strings for (int p = 0; p < len; p++) { if (temp1[p] == temp2[p]) XOR += "0"; else XOR += "1"; } return XOR; } string maxValUtil(string bin_str) { // String length int len = bin_str.size(); int leftZero = -1, cnt0 = 0, cnt1 = 0; // Calculate number of 0's and 1's in the given string. for (int p = 0; p < len; p++) { if (bin_str[p] == '1') { cnt1++; } else { // For the left most '0' if (leftZero == -1) { leftZero = p; } cnt0++; } } // Case 1 - When the string contains all 1's if (cnt1 == len) { return getXOR(bin_str, "1"); } // Case 2 - When the string contains all zeros if (cnt0 == len) { return "0"; } // Take the substring starting from left most '0' as we need to maximize it string rightStr = bin_str.substr(leftZero, len - leftZero); int size = rightStr.size(); string temp = rightStr; string maxRes = ""; string temp1 = "", temp2 = ""; // Choosing the second string for (int q = 0; q < len; q++) { // Finding the substring of length 'size' from start if (q < size) { temp1 += bin_str[q]; } else { // If temp1 gives the maximum XOR result, choose it as a second string string res = getXOR(temp, temp1); if (res > maxRes) { maxRes = res; temp2 = temp1; } // Update temp1 string temp1 = temp1.substr(1); temp1 += bin_str[q]; } } // Handling the last case string res = getXOR(temp1, temp); if (res > maxRes) { maxRes = res; temp2 = rightStr; } // Take the XOR of the original string and the second string string answer = getXOR(bin_str, temp2); leftZero = -1; for (int p = 0; p < answer.size(); p++) { // Remove initial zeros if (answer[p] != '0') { leftZero = p; break; } } if (leftZero == -1) { return "0"; } // Final maximum string return answer.substr(leftZero); } string findMaxValue(string bin_str, int K) { // Find the maximum value of the updated binary string for (int p = 0; p < K; p++) { bin_str = maxValUtil(bin_str); } return bin_str; } int main() { string bin_str = "1101"; int K = 1; cout << "The maximum value of the string after performing " << K << " XOR operations is - " << findMaxValue(bin_str, K) << endl; return 0; }
Output
The maximum value of the string after performing 1 XOR operations is - 1111
public class Main { // Function to calculate XOR of two strings public static String getXOR(String temp1, String temp2) { int len1 = temp1.length(); int len2 = temp2.length(); int length = Math.max(len1, len2); // Add leading zeros to the shorter string if (len1 > len2) { temp2 = "0".repeat(len1 - len2) + temp2; } else if (len2 > len1) { temp1 = "0".repeat(len2 - len1) + temp1; } StringBuilder XOR = new StringBuilder(); // Perform XOR of both strings for (int i = 0; i < length; i++) { XOR.append(temp1.charAt(i) == temp2.charAt(i) ? '0' : '1'); } return XOR.toString(); } // Function to find the maximum value substring public static String maxValUtil(String bin_str) { int length = bin_str.length(); int leftZero = -1; int cnt0 = 0, cnt1 = 0; // Count the number of 0's and 1's in the binary string for (int i = 0; i < length; i++) { if (bin_str.charAt(i) == '1') { cnt1++; } else { if (leftZero == -1) { leftZero = i; } cnt0++; } } // Case 1: All 1's in the string if (cnt1 == length) { return getXOR(bin_str, "1"); } // Case 2: All 0's in the string if (cnt0 == length) { return "0"; } // Find the substring starting from the leftmost '0' String rightStr = bin_str.substring(leftZero); int size = rightStr.length(); String temp = rightStr; String maxRes = ""; String temp1 = ""; String temp2 = ""; // Choosing the second string for (int i = 0; i < length; i++) { if (i < size) { temp1 += bin_str.charAt(i); } else { String res = getXOR(temp, temp1); if (res.compareTo(maxRes) > 0) { maxRes = res; temp2 = temp1; } temp1 = temp1.substring(1) + bin_str.charAt(i); } } // Handling the last case String res = getXOR(temp1, temp); if (res.compareTo(maxRes) > 0) { maxRes = res; temp2 = rightStr; } // Take the XOR of the original string and the second string String answer = getXOR(bin_str, temp2); leftZero = -1; // Remove leading zeros for (int i = 0; i < answer.length(); i++) { if (answer.charAt(i) != '0') { leftZero = i; break; } } if (leftZero == -1) { return "0"; } // Final maximum string return answer.substring(leftZero); } // Function to find the maximum value of the binary string after K XOR operations public static String findMaxValue(String bin_str, int K) { for (int i = 0; i < K; i++) { bin_str = maxValUtil(bin_str); } return bin_str; } public static void main(String[] args) { String bin_str = "1101"; int K = 1; String result = findMaxValue(bin_str, K); System.out.println("The maximum value of the string after performing " + K + " XOR operations is - " + result); } }
Output
The maximum value of the string after performing 1 XOR operations is - 1111
def addNZero(substr, n): for _ in range(n): substr = '0' + substr # Finding XOR of two strings def getXOR(temp1, temp2): # Get string sizes temp1_len = len(temp1) temp2_len = len(temp2) # Append zeros to the smaller string if temp1_len > temp2_len: temp2 = '0' * (temp1_len - temp2_len) + temp2 elif temp2_len > temp1_len: temp1 = '0' * (temp2_len - temp1_len) + temp1 # Final string length length = max(temp1_len, temp2_len) # Take XOR of both strings result = '' for p in range(length): if temp1[p] == temp2[p]: result += '0' else: result += '1' return result def maxValUtil(bin_str): # String length length = len(bin_str) leftZero = -1 cnt0 = 0 cnt1 = 0 # Calculate the number of 0's and 1's in the given string. for p in range(length): if bin_str[p] == '1': cnt1 += 1 else: # For the leftmost '0' if leftZero == -1: leftZero = p cnt0 += 1 # Case 1 - When the string contains all 1's if cnt1 == length: return getXOR(bin_str, '1') # Case 2 - When the string contains all zeros if cnt0 == length: return '0' # Take the substring starting from the leftmost '0' as we need to maximize it rightStr = bin_str[leftZero:] size = len(rightStr) temp = rightStr maxRes = '' temp1 = '' temp2 = '' # Choosing the second string for q in range(length): # Finding the substring of length 'size' from start if q < size: temp1 += bin_str[q] else: # If temp1 gives the maximum XOR result, choose it as the second string res = getXOR(temp, temp1) if res > maxRes: maxRes = res temp2 = temp1 # Update temp1 string temp1 = temp1[1:] + bin_str[q] # Handling the last case res = getXOR(temp1, temp) if res > maxRes: maxRes = res temp2 = rightStr # Take the XOR of the original string and the second string answer = getXOR(bin_str, temp2) leftZero = -1 for p in range(len(answer)): # Remove initial zeros if answer[p] != '0': leftZero = p break if leftZero == -1: return '0' # Final maximum string return answer[leftZero:] def findMaxValue(bin_str, K): # Find the maximum value of the updated binary string for _ in range(K): bin_str = maxValUtil(bin_str) return bin_str bin_str = '1101' K = 1 result = findMaxValue(bin_str, K) print(f"The maximum value of the string after performing {K} XOR operations is - {result}")
Output
The maximum value of the string after performing 1 XOR operations is - 1111
Time complexity - O(N*N*K), where O(N) is for finding substring to maximize binary string, another O(N) is to perform the XOR operation of two strings, and O(K) is to perform total K operations.
Space complexity - O(N) to store the temporary strings.