通过执行子字符串的异或运算,在 K 步内最大化二进制字符串的值
在这个问题中,我们将通过对给定二进制字符串的子字符串执行 K 次异或运算来最大化二进制字符串的值。
为了最大化任何二进制字符串,我们应该最大化从最左侧零开始的子字符串。例如,要最大化字符串“11001”,我们需要选择另一个子字符串,以便我们可以最大化“001”子字符串。
问题陈述
我们给定一个名为 bin_str 的二进制字符串,包含 N 个字符。我们必须通过对任何两个子字符串执行异或运算,在 K 次操作中最大化二进制字符串的值。给定子字符串可以是相同、相交或不相交的。
示例
输入
bin_str = "1101"; K = 1;
输出
1111
解释
我们可以取 10 和 1101 子字符串,当我们对两者执行异或运算时,我们得到最大字符串 1111。
输入
bin_str = "110101"; K = 2
输出
111110
解释
在第一次操作中,我们可以取 110101 和 1010 子字符串。当我们对这两个字符串执行异或运算时,我们得到二进制字符串 111111。
在第二次操作中,我们可以取 111111 和 1 子字符串,当我们对两者执行异或运算时,我们得到 111110,这是我们可以得到的最大字符串。
输入
bin_str = "01"; K = 1;
输出
1
解释
取 01 和 0 子字符串得到 1。
方法 1
在这种方法中,我们将从最左侧的 0 到末尾取一个子字符串,并找到字符串的另一个子字符串以获得最大的二进制字符串值。
例如,二进制字符串是 1110010101。要最大化二进制字符串,我们需要最大化 0010101 子字符串。因此,我们将取二进制字符串本身作为第一个子字符串,并取相同长度的另一个字符串“0010101”来最大化二进制字符串。
算法
步骤 1 - 对 K 次执行 maxValUtil() 函数,并使用其返回值更新二进制字符串。
步骤 2 - 在 maxValUtil() 函数中,将“leftZero”初始化为 -1 以存储最左侧零的索引,“cnt0”和“cnt1”初始化为 0 以分别存储二进制字符串中 0 和 1 的数量。
步骤 3 - 遍历字符串,如果当前字符是“1”,则将“cnt1”加 1。否则,如果“leftZero”是 -1,则将其值更新为当前索引并将“cnt0”值加 1。
步骤 4 - 如果“cnt1”和“len”相等,则取二进制字符串与“1”的异或,并返回其值。
步骤 4.1 - 在 getXOR() 函数中获取两个字符串的长度。如果两个字符串长度不相等,则通过执行 addZeros() 函数在长度较小的字符串前面添加零。
步骤 4.1.1 - 在 addZero() 函数中,在字符串的开头附加所需的零。
步骤 4.2 - 初始化“XOR”字符串以存储对两个字符串执行异或运算后的结果。
步骤 4.3 - 遍历两个字符串,如果两个字符串中第 p 个索引处的字符相同,则将“0”附加到 XOR 字符串。否则,将“1”附加到 XOR 字符串。
步骤 4.4 - 返回 XOR 字符串。
步骤 5 - 在 maxValUtil() 函数中,如果“cnt0”等于二进制字符串的长度,则返回“0”。
步骤 6 - 使用 substr() 方法初始化“rightStr”字符串,该字符串从“leftZero”索引开始。还将“size”初始化为“rightStr”字符串的大小,“temp”初始化为“rightStr”字符串,“maxRes”、“temp1”和“temp2”初始化为空字符串。
步骤 7 - 开始遍历二进制字符串。如果索引小于“size”变量的值,则将字符附加到“temp1”字符串。
步骤 8 - 否则,获取“temp”和“temp1”字符串的异或。如果异或值超过“maxRes”字符串的值,则将“maxRes”更新为“res”并将“temp2”更新为“temp1”。此外,从“temp1”字符串中删除第一个字符,并在末尾附加当前字符。
在这里,我们找到“temp2”子字符串,使得“temp1”和“temp2”的异或最大化,以最大化二进制字符串。
步骤 9 - 处理我们取 temp1 字符串与 rightStr 字符串的异或的最后一个情况。
步骤 10 - 接下来,取二进制字符串和 temp2 字符串的异或,并将结果存储在答案中。
步骤 11 - 删除前导零后返回“answer”字符串。
示例
以下是上述算法的程序 -
#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;
}
输出
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;
}
输出
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);
}
}
输出
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}")
输出
The maximum value of the string after performing 1 XOR operations is - 1111
时间复杂度 – O(N*N*K),其中 O(N) 用于查找最大化二进制字符串的子字符串,另一个 O(N) 用于执行两个字符串的异或运算,O(K) 用于执行总共 K 次操作。
空间复杂度 – O(N) 用于存储临时字符串。
数据结构
网络
关系型数据库管理系统
操作系统
Java
iOS
HTML
CSS
Android
Python
C 编程
C++
C#
MongoDB
MySQL
Javascript
PHP