Maximize [length(X)/2^(XOR(X, Y))] by choosing substrings X and Y from string A and B respectively
Given two binary strings A and B of size N and M respectively, the task is to maximize the value of the length of (X) / 2XOR(X, Y) by choosing two substrings X and Y of equal length from the given string A and B respectively.
Examples:
Input: A = “0110”, B = “1101”
Output: 3
Explanation:
Choose the substring “110” and “110” from the string A and B respectively. The value of the expression of length(X) / 2XOR(X, Y) is 3 / 20 = 3, which is maximum among all possible combinations.
Input: A = “1111”, B = “0000”
Output: 0
Approach: The given problem can be solved by observing the expression that it needs to be maximized, therefore the denominator must be minimum, and to minimize it the value of Bitwise XOR of the substrings X and Y must be minimum i.e., zero and to make the value of Bitwise XOR as zero, the two substrings must be same. Therefore, the problem reduces to finding the Longest Common Substring of both the strings A and B. Follow the steps below to solve the problem:
- Initialize a 2D array, say LCSuff[M + 1][N + 1] to store the lengths of the longest common suffixes of the substrings.
- Initialize a variable, say result as 0 to store the result maximum value of the given expression.
- Iterate over the range [0, M] using the variable i and nested iterate over the range [0, N] using the variable j and perform the following steps:
- If i equals 0 or j equals 0, then update the value of LCSSuff[i][j] equals 0.
- Otherwise, if the value of A[i – 1] equals A[j – 1] then update the value of LCSSuff[i][j] as LCSSuff[i – 1][j – 1] + 1 and update the value of result as the maximum of result and LCSSuff[i][j].
- Otherwise, update the value of LCSSuff[i][j] to 0.
- After completing the above steps, print the value of result as the result.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int LCSubStr( char * A, char * B, int m, int n)
{
int LCSuff[m + 1][n + 1];
int result = 0;
for ( int i = 0; i <= m; i++) {
for ( int j = 0; j <= n; j++) {
if (i == 0 || j == 0)
LCSuff[i][j] = 0;
else if (A[i - 1] == B[j - 1]) {
LCSuff[i][j]
= LCSuff[i - 1][j - 1]
+ 1;
result = max(result,
LCSuff[i][j]);
}
else
LCSuff[i][j] = 0;
}
}
return result;
}
int main()
{
char A[] = "0110" ;
char B[] = "1101" ;
int M = strlen (A);
int N = strlen (B);
cout << LCSubStr(A, B, M, N);
return 0;
}
|
Java
class GFG{
static int lcsubtr( char a[], char b[], int length1,
int length2)
{
int dp[][] = new int [length1 + 1 ][length2 + 1 ];
int max = 0 ;
for ( int i = 0 ; i <= length1; ++i)
{
for ( int j = 0 ; j <= length2; ++j)
{
if (i == 0 || j == 0 )
{
dp[i][j] = 0 ;
}
else if (a[i - 1 ] == b[j - 1 ])
{
dp[i][j] = dp[i - 1 ][j - 1 ] + 1 ;
max = Math.max(dp[i][j], max);
}
else
{
dp[i][j] = 0 ;
}
}
}
return max;
}
public static void main(String[] args)
{
String m = "0110" ;
String n = "1101" ;
char m1[] = m.toCharArray();
char m2[] = n.toCharArray();
System.out.println(lcsubtr(m1, m2, m1.length,
m2.length));
}
}
|
Python3
def LCSubStr(A, B, m, n):
LCSuff = [[ 0 for i in range (n + 1 )] for j in range (m + 1 )]
result = 0
for i in range (m + 1 ):
for j in range (n + 1 ):
if (i = = 0 or j = = 0 ):
LCSuff[i][j] = 0
elif (A[i - 1 ] = = B[j - 1 ]):
LCSuff[i][j] = LCSuff[i - 1 ][j - 1 ] + 1
result = max (result,LCSuff[i][j])
else :
LCSuff[i][j] = 0
return result
if __name__ = = '__main__' :
A = "0110"
B = "1101"
M = len (A)
N = len (B)
print (LCSubStr(A, B, M, N))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int lcsubtr( char [] a, char [] b, int length1,
int length2)
{
int [,] dp = new int [length1 + 1, length2 + 1];
int max = 0;
for ( int i = 0; i <= length1; ++i)
{
for ( int j = 0; j <= length2; ++j)
{
if (i == 0 || j == 0)
{
dp[i, j] = 0;
}
else if (a[i - 1] == b[j - 1])
{
dp[i, j] = dp[i - 1, j - 1] + 1;
max = Math.Max(dp[i, j], max);
}
else
{
dp[i, j] = 0;
}
}
}
return max;
}
public static void Main()
{
string m = "0110" ;
string n = "1101" ;
char [] m1 = m.ToCharArray();
char [] m2 = n.ToCharArray();
Console.Write(lcsubtr(m1, m2, m1.Length,
m2.Length));
}
}
|
Javascript
<script>
function LCSubStr(A, B, m, n)
{
let LCSuff = Array(m + 1).fill(Array(n + 1));
let result = 0;
for (let i = 0; i <= m; i++) {
for (let j = 0; j <= n; j++) {
if (i == 0 || j == 0)
LCSuff[i][j] = 0;
else if (A.charAt(i - 1) == B.charAt(j - 1)) {
LCSuff[i][j] = LCSuff[i - 1][j - 1] + 1;
if (LCSuff[i][j] > result) {
result = LCSuff[i][j];
}
}
else
LCSuff[i][j] = 0;
}
}
result++;
return result;
}
let A = "0110" ;
let B = "1101" ;
let M = A.length;
let N = B.length;
document.write(LCSubStr(A, B, M, N));
</script>
|
Time Complexity: O(M*N)
Auxiliary Space: O(M*N)
Efficient approach : Space optimization
In previous approach the current value LCSuff[i][j] is only depend upon the current and previous row values of matrix. So to optimize the space complexity we use a single 1D array to store the computations.
Implementation steps:
- Create a 1D vector LCSuff of size n+1.
- Set a base case by initializing the values of LCSuff.
- Now iterate over subproblems by the help of nested loop and get the current value from previous computations.
- Now Create a temporary variables prev used to store previous computations and temp for current value.
- After every iteration assign the value of temp to prev for further iteration.
- Initialize a variable result to store the final answer and update it by iterating through the LCSuff.
- At last return and print the final answer stored in result.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int LCSubStr( char * A, char * B, int m, int n)
{
int LCSuff[n + 1];
int result = 0;
for ( int i = 0; i <= m; i++) {
int prev = 0;
for ( int j = 0; j <= n; j++) {
int temp = LCSuff[j];
if (i == 0 || j == 0)
LCSuff[j] = 0;
else if (A[i - 1] == B[j - 1]) {
LCSuff[j] = prev + 1;
result = max(result, LCSuff[j]);
}
else
LCSuff[j] = 0;
prev = temp;
}
}
return result;
}
int main()
{
char A[] = "0110" ;
char B[] = "1101" ;
int M = strlen (A);
int N = strlen (B);
cout << LCSubStr(A, B, M, N);
return 0;
}
|
Java
import java.util.*;
public class Main
{
public static int LCSubStr( char [] A, char [] B, int m, int n)
{
int [] LCSuff = new int [n + 1 ];
int result = 0 ;
for ( int i = 0 ; i <= m; i++) {
int prev = 0 ;
for ( int j = 0 ; j <= n; j++) {
int temp = LCSuff[j];
if (i == 0 || j == 0 )
LCSuff[j] = 0 ;
else if (A[i - 1 ] == B[j - 1 ]) {
LCSuff[j] = prev + 1 ;
result = Math.max(result, LCSuff[j]);
}
else
LCSuff[j] = 0 ;
prev = temp;
}
}
return result;
}
public static void main(String[] args) {
char [] A = "0110" .toCharArray();
char [] B = "1101" .toCharArray();
int M = A.length;
int N = B.length;
System.out.println(LCSubStr(A, B, M, N));
}
}
|
Python
def LCSubStr(A, B, m, n):
LCSuff = [ 0 ] * (n + 1 )
result = 0
for i in range (m + 1 ):
prev = 0
for j in range (n + 1 ):
temp = LCSuff[j]
if i = = 0 or j = = 0 :
LCSuff[j] = 0
elif A[i - 1 ] = = B[j - 1 ]:
LCSuff[j] = prev + 1
result = max (result, LCSuff[j])
else :
LCSuff[j] = 0
prev = temp
return result
A = "0110"
B = "1101"
M = len (A)
N = len (B)
print (LCSubStr(A, B, M, N))
|
C#
using System;
public class GFG
{
public static int LCSubStr( char [] A, char [] B, int m, int n)
{
int [] LCSuff = new int [n + 1];
int result = 0;
for ( int i = 0; i <= m; i++)
{
int prev = 0;
for ( int j = 0; j <= n; j++)
{
int temp = LCSuff[j];
if (i == 0 || j == 0)
LCSuff[j] = 0;
else if (A[i - 1] == B[j - 1])
{
LCSuff[j] = prev + 1;
result = Math.Max(result, LCSuff[j]);
}
else
LCSuff[j] = 0;
prev = temp;
}
}
return result;
}
public static void Main( string [] args)
{
char [] A = "0110" .ToCharArray();
char [] B = "1101" .ToCharArray();
int M = A.Length;
int N = B.Length;
Console.WriteLine(LCSubStr(A, B, M, N));
}
}
|
Javascript
function LCSubStr(A, B, m, n) {
const LCSuff = new Array(n + 1).fill(0);
let result = 0;
for (let i = 0; i <= m; i++) {
let prev = 0;
for (let j = 0; j <= n; j++) {
let temp = LCSuff[j];
if (i === 0 || j === 0)
LCSuff[j] = 0;
else if (A[i - 1] === B[j - 1]) {
LCSuff[j] = prev + 1;
result = Math.max(result, LCSuff[j]);
}
else
LCSuff[j] = 0;
prev = temp;
}
}
return result;
}
const A = "0110" ;
const B = "1101" ;
const M = A.length;
const N = B.length;
console.log(LCSubStr(A, B, M, N));
|
Output:
3
Time Complexity: O(M*N)
Auxiliary Space: O(N)
Last Updated :
19 Sep, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...