Longest Span with same Sum in two Binary arrays
Given two binary arrays, arr1[] and arr2[] of the same size n. Find the length of the longest common span (i, j) where j >= i such that arr1[i] + arr1[i+1] + …. + arr1[j] = arr2[i] + arr2[i+1] + …. + arr2[j].
The expected time complexity is ?(n).
Examples:
Input: arr1[] = {0, 1, 0, 0, 0, 0};
arr2[] = {1, 0, 1, 0, 0, 1};
Output: 4
The longest span with same sum is from index 1 to 4.
Input: arr1[] = {0, 1, 0, 1, 1, 1, 1};
arr2[] = {1, 1, 1, 1, 1, 0, 1};
Output: 6
The longest span with same sum is from index 1 to 6.
Input: arr1[] = {0, 0, 0};
arr2[] = {1, 1, 1};
Output: 0
Input: arr1[] = {0, 0, 1, 0};
arr2[] = {1, 1, 1, 1};
Output: 1
Method 1 (Simple Solution)
One by one by consider same subarrays of both arrays. For all subarrays, compute sums and if sums are same and current length is more than max length, then update max length. Below is C++ implementation of the simple approach.
C++
#include<bits/stdc++.h>
using namespace std;
int longestCommonSum( bool arr1[], bool arr2[], int n)
{
int maxLen = 0;
for ( int i=0; i<n; i++)
{
int sum1 = 0, sum2 = 0;
for ( int j=i; j<n; j++)
{
sum1 += arr1[j];
sum2 += arr2[j];
if (sum1 == sum2)
{
int len = j-i+1;
if (len > maxLen)
maxLen = len;
}
}
}
return maxLen;
}
int main()
{
bool arr1[] = {0, 1, 0, 1, 1, 1, 1};
bool arr2[] = {1, 1, 1, 1, 1, 0, 1};
int n = sizeof (arr1)/ sizeof (arr1[0]);
cout << "Length of the longest common span with same "
"sum is " << longestCommonSum(arr1, arr2, n);
return 0;
}
|
Java
class Test
{
static int arr1[] = new int []{ 0 , 1 , 0 , 1 , 1 , 1 , 1 };
static int arr2[] = new int []{ 1 , 1 , 1 , 1 , 1 , 0 , 1 };
static int longestCommonSum( int n)
{
int maxLen = 0 ;
for ( int i= 0 ; i<n; i++)
{
int sum1 = 0 , sum2 = 0 ;
for ( int j=i; j<n; j++)
{
sum1 += arr1[j];
sum2 += arr2[j];
if (sum1 == sum2)
{
int len = j-i+ 1 ;
if (len > maxLen)
maxLen = len;
}
}
}
return maxLen;
}
public static void main(String[] args)
{
System.out.print( "Length of the longest common span with same sum is " );
System.out.println(longestCommonSum(arr1.length));
}
}
|
Python3
def longestCommonSum(arr1, arr2, n):
maxLen = 0
for i in range ( 0 ,n):
sum1 = 0
sum2 = 0
for j in range (i,n):
sum1 + = arr1[j]
sum2 + = arr2[j]
if (sum1 = = sum2):
len = j - i + 1
if ( len > maxLen):
maxLen = len
return maxLen
arr1 = [ 0 , 1 , 0 , 1 , 1 , 1 , 1 ]
arr2 = [ 1 , 1 , 1 , 1 , 1 , 0 , 1 ]
n = len (arr1)
print ( "Length of the longest common span with same "
"sum is" ,longestCommonSum(arr1, arr2, n))
|
C#
using System;
class GFG
{
static int [] arr1 = new int []{0, 1, 0, 1, 1, 1, 1};
static int [] arr2 = new int []{1, 1, 1, 1, 1, 0, 1};
static int longestCommonSum( int n)
{
int maxLen = 0;
for ( int i = 0; i < n; i++)
{
int sum1 = 0, sum2 = 0;
for ( int j = i; j < n; j++)
{
sum1 += arr1[j];
sum2 += arr2[j];
if (sum1 == sum2)
{
int len = j - i + 1;
if (len > maxLen)
maxLen = len;
}
}
}
return maxLen;
}
public static void Main()
{
Console.Write( "Length of the longest " +
"common span with same sum is " );
Console.Write(longestCommonSum(arr1.Length));
}
}
|
PHP
<?php
function longestCommonSum( $arr1 , $arr2 , $n )
{
$maxLen = 0;
for ( $i = 0; $i < $n ; $i ++)
{
$sum1 = 0; $sum2 = 0;
for ( $j = $i ; $j < $n ; $j ++)
{
$sum1 += $arr1 [ $j ];
$sum2 += $arr2 [ $j ];
if ( $sum1 == $sum2 )
{
$len = $j - $i + 1;
if ( $len > $maxLen )
$maxLen = $len ;
}
}
}
return $maxLen ;
}
$arr1 = array (0, 1, 0, 1, 1, 1, 1);
$arr2 = array (1, 1, 1, 1, 1, 0, 1);
$n = sizeof( $arr1 );
echo "Length of the longest common span " .
"with same " , "sum is " ,
longestCommonSum( $arr1 , $arr2 , $n );
?>
|
Javascript
<script>
let arr1 = [0, 1, 0, 1, 1, 1, 1];
let arr2 = [1, 1, 1, 1, 1, 0, 1];
function longestCommonSum(n)
{
let maxLen = 0;
for (let i = 0; i < n; i++)
{
let sum1 = 0, sum2 = 0;
for (let j = i; j < n; j++)
{
sum1 += arr1[j];
sum2 += arr2[j];
if (sum1 == sum2)
{
let len = j - i + 1;
if (len > maxLen)
maxLen = len;
}
}
}
return maxLen;
}
document.write( "Length of the longest " + "common span with same sum is " );
document.write(longestCommonSum(arr1.length));
</script>
|
Output :
Length of the longest common span with same sum is 6
Time Complexity : O(n2)
Auxiliary Space : O(1)
Method 2 (Using Auxiliary Array)
The idea is based on the below observations.
- Since there are total n elements, maximum sum is n for both arrays.
- The difference between two sums varies from -n to n. So there are total 2n + 1 possible values of difference.
- If differences between prefix sums of two arrays become same at two points, then subarrays between these two points have same sum.
Below is the Complete Algorithm.
- Create an auxiliary array of size 2n+1 to store starting points of all possible values of differences (Note that possible values of differences vary from -n to n, i.e., there are total 2n+1 possible values)
- Initialize starting points of all differences as -1.
- Initialize maxLen as 0 and prefix sums of both arrays as 0, preSum1 = 0, preSum2 = 0
- Traverse both arrays from i = 0 to n-1.
- Update prefix sums: preSum1 += arr1[i], preSum2 += arr2[i]
- Compute difference of current prefix sums: curr_diff = preSum1 – preSum2
- Find index in diff array: diffIndex = n + curr_diff // curr_diff can be negative and can go till -n
- If curr_diff is 0, then i+1 is maxLen so far
- Else If curr_diff is seen first time, i.e., starting point of current diff is -1, then update starting point as i
- Else (curr_diff is NOT seen first time), then consider i as ending point and find length of current same sum span. If this length is more, then update maxLen
- Return maxLen
Below is the implementation of above algorithm.
C++
#include<bits/stdc++.h>
using namespace std;
int longestCommonSum( bool arr1[], bool arr2[], int n)
{
int maxLen = 0;
int preSum1 = 0, preSum2 = 0;
int diff[2*n+1];
memset (diff, -1, sizeof (diff));
for ( int i=0; i<n; i++)
{
preSum1 += arr1[i];
preSum2 += arr2[i];
int curr_diff = preSum1 - preSum2;
int diffIndex = n + curr_diff;
if (curr_diff == 0)
maxLen = i+1;
else if ( diff[diffIndex] == -1)
diff[diffIndex] = i;
else
{
int len = i - diff[diffIndex];
maxLen = max(maxLen,len);
}
}
return maxLen;
}
int main()
{
bool arr1[] = {0, 1, 0, 1, 1, 1, 1};
bool arr2[] = {1, 1, 1, 1, 1, 0, 1};
int n = sizeof (arr1)/ sizeof (arr1[0]);
cout << "Length of the longest common span with same "
"sum is " << longestCommonSum(arr1, arr2, n);
return 0;
}
|
Java
class Test
{
static int arr1[] = new int []{ 0 , 1 , 0 , 1 , 1 , 1 , 1 };
static int arr2[] = new int []{ 1 , 1 , 1 , 1 , 1 , 0 , 1 };
static int longestCommonSum( int n)
{
int maxLen = 0 ;
int preSum1 = 0 , preSum2 = 0 ;
int diff[] = new int [ 2 *n+ 1 ];
for ( int i = 0 ; i < diff.length; i++) {
diff[i] = - 1 ;
}
for ( int i= 0 ; i<n; i++)
{
preSum1 += arr1[i];
preSum2 += arr2[i];
int curr_diff = preSum1 - preSum2;
int diffIndex = n + curr_diff;
if (curr_diff == 0 )
maxLen = i+ 1 ;
else if ( diff[diffIndex] == - 1 )
diff[diffIndex] = i;
else
{
int len = i - diff[diffIndex];
if (len > maxLen)
maxLen = len;
}
}
return maxLen;
}
public static void main(String[] args)
{
System.out.print( "Length of the longest common span with same sum is " );
System.out.println(longestCommonSum(arr1.length));
}
}
|
Python
def longestCommonSum(arr1, arr2, n):
maxLen = 0
presum1 = presum2 = 0
diff = {}
for i in range (n):
presum1 + = arr1[i]
presum2 + = arr2[i]
curr_diff = presum1 - presum2
if curr_diff = = 0 :
maxLen = i + 1
elif curr_diff not in diff:
diff[curr_diff] = i
else :
length = i - diff[curr_diff]
maxLen = max (maxLen, length)
return maxLen
arr1 = [ 0 , 1 , 0 , 1 , 1 , 1 , 1 ]
arr2 = [ 1 , 1 , 1 , 1 , 1 , 0 , 1 ]
print ( "Length of the longest common" ,
" span with same" , end = " " )
print ( "sum is" ,longestCommonSum(arr1,
arr2, len (arr1)))
|
C#
using System;
class GFG
{
static int [] arr1 = new int []{0, 1, 0, 1, 1, 1, 1};
static int [] arr2 = new int []{1, 1, 1, 1, 1, 0, 1};
static int longestCommonSum( int n)
{
int maxLen = 0;
int preSum1 = 0, preSum2 = 0;
int [] diff = new int [2 * n + 1];
for ( int i = 0; i < diff.Length; i++)
{
diff[i] = -1;
}
for ( int i = 0; i < n; i++)
{
preSum1 += arr1[i];
preSum2 += arr2[i];
int curr_diff = preSum1 - preSum2;
int diffIndex = n + curr_diff;
if (curr_diff == 0)
maxLen = i + 1;
else if ( diff[diffIndex] == -1)
diff[diffIndex] = i;
else
{
int len = i - diff[diffIndex];
if (len > maxLen)
maxLen = len;
}
}
return maxLen;
}
public static void Main()
{
Console.Write( "Length of the longest common " +
"span with same sum is " );
Console.WriteLine(longestCommonSum(arr1.Length));
}
}
|
Javascript
<script>
let arr1 = [0, 1, 0, 1, 1, 1, 1];
let arr2 = [1, 1, 1, 1, 1, 0, 1];
function longestCommonSum(n)
{
let maxLen = 0;
let preSum1 = 0, preSum2 = 0;
let diff = new Array(2 * n + 1);
for (let i = 0; i < diff.length; i++)
{
diff[i] = -1;
}
for (let i = 0; i < n; i++)
{
preSum1 += arr1[i];
preSum2 += arr2[i];
let curr_diff = preSum1 - preSum2;
let diffIndex = n + curr_diff;
if (curr_diff == 0)
maxLen = i + 1;
else if ( diff[diffIndex] == -1)
diff[diffIndex] = i;
else
{
let len = i - diff[diffIndex];
if (len > maxLen)
maxLen = len;
}
}
return maxLen;
}
document.write( "Length of the longest common "
+ "span with same sum is " );
document.write(longestCommonSum(arr1.length));
</script>
|
Output:
Length of the longest common span with same sum is 6
Time Complexity: O(n)
Auxiliary Space: O(n)
Method 3 (Using Hashing)
- Find difference array arr[] such that arr[i] = arr1[i] – arr2[i].
- Largest subarray with equal number of 0s and 1s in the difference array.
C++
#include <bits/stdc++.h>
using namespace std;
int longestCommonSum( bool arr1[], bool arr2[], int n)
{
int arr[n];
for ( int i=0; i<n; i++)
arr[i] = arr1[i] - arr2[i];
unordered_map< int , int > hM;
int sum = 0;
int max_len = 0;
for ( int i = 0; i < n; i++)
{
sum += arr[i];
if (sum == 0)
max_len = i + 1;
if (hM.find(sum) != hM.end())
max_len = max(max_len, i - hM[sum]);
else
hM[sum] = i;
}
return max_len;
}
int main()
{
bool arr1[] = {0, 1, 0, 1, 1, 1, 1};
bool arr2[] = {1, 1, 1, 1, 1, 0, 1};
int n = sizeof (arr1)/ sizeof (arr1[0]);
cout << longestCommonSum(arr1, arr2, n);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG
{
static int longestCommonSum( int [] arr1, int [] arr2, int n)
{
int [] arr = new int [n];
for ( int i = 0 ; i < n; i++)
arr[i] = arr1[i] - arr2[i];
HashMap<Integer, Integer> hM = new HashMap<>();
int sum = 0 ;
int max_len = 0 ;
for ( int i = 0 ; i < n; i++)
{
sum += arr[i];
if (sum == 0 )
max_len = i + 1 ;
if (hM.containsKey(sum))
max_len = Math.max(max_len, i - hM.get(sum));
else
hM.put(sum, i);
}
return max_len;
}
public static void main(String args[])
{
int [] arr1 = { 0 , 1 , 0 , 1 , 1 , 1 , 1 };
int [] arr2 = { 1 , 1 , 1 , 1 , 1 , 0 , 1 };
int n = arr1.length;
System.out.println(longestCommonSum(arr1, arr2, n));
}
}
|
Python3
def longestCommonSum(arr1, arr2, n):
arr = [ 0 for i in range (n)]
for i in range (n):
arr[i] = arr1[i] - arr2[i];
hm = {}
sum = 0
max_len = 0
for i in range (n):
sum + = arr[i]
if ( sum = = 0 ):
max_len = i + 1
if sum in hm:
max_len = max (max_len, i - hm[ sum ])
else :
hm[ sum ] = i
return max_len
arr1 = [ 0 , 1 , 0 , 1 , 1 , 1 , 1 ]
arr2 = [ 1 , 1 , 1 , 1 , 1 , 0 , 1 ]
n = len (arr1)
print (longestCommonSum(arr1, arr2, n))
|
C#
using System;
using System.Collections.Generic;
public class GFG
{
static int longestCommonSum( int [] arr1, int [] arr2, int n)
{
int [] arr = new int [n];
for ( int i = 0; i < n; i++)
arr[i] = arr1[i] - arr2[i];
Dictionary< int , int > hM = new Dictionary< int , int >();
int sum = 0;
int max_len = 0;
for ( int i = 0; i < n; i++)
{
sum += arr[i];
if (sum == 0)
max_len = i + 1;
if (hM.ContainsKey(sum))
max_len = Math.Max(max_len, i - hM[sum]);
else
hM[sum] = i;
}
return max_len;
}
static public void Main ()
{
int [] arr1 = {0, 1, 0, 1, 1, 1, 1};
int [] arr2 = {1, 1, 1, 1, 1, 0, 1};
int n = arr1.Length;
Console.WriteLine(longestCommonSum(arr1, arr2, n));
}
}
|
Javascript
<script>
function longestCommonSum(arr1,arr2,n)
{
let arr = new Array(n);
for (let i = 0; i < n; i++)
arr[i] = arr1[i] - arr2[i];
let hM = new Map();
let sum = 0;
let max_len = 0;
for (let i = 0; i < n; i++)
{
sum += arr[i];
if (sum == 0)
max_len = i + 1;
if (hM.has(sum))
max_len = Math.max(max_len, i - hM.get(sum));
else
hM.set(sum, i);
}
return max_len;
}
let arr1=[0, 1, 0, 1, 1, 1, 1];
let arr2=[1, 1, 1, 1, 1, 0, 1];
let n = arr1.length;
document.write(longestCommonSum(arr1, arr2, n));
</script>
|
Output:
6
Time Complexity: O(n) (As the array is traversed only once.)
Auxiliary Space: O(n) (As hashmap has been used which takes extra space.)
-r_Ahs
Last Updated :
18 Sep, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...