透過執行子字串的異或運算,在 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