Open In App

Longest Span with same Sum in two Binary arrays

Last Updated : 10 Oct, 2024
Summarize
Comments
Improve
Suggest changes
Like Article
Like
Share
Report
News Follow

Given two binary arrays, a[] and b[] of the same size n. Find the length of the longest common span (i, j) where j >= i such that a[i] + a[i+1] + …. + a[j] = b[i] + b[i+1] + …. + b[j].

Examples:  

Input: a[] = {0, 1, 0, 0, 0, 0}
b[] = {1, 0, 1, 0, 0, 1}
Output: 4
The longest span with same sum is from index 1 to 4.

Input: a[] = {0, 1, 0, 1, 1, 1, 1}
b[] = {1, 1, 1, 1, 1, 0, 1}
Output: 6
The longest span with same sum is from index 1 to 6.

Input: a[] = {0, 0, 0}
b[] = {1, 1, 1}
Output: 0

Input: a[] = {0, 0, 1, 0}
b[] = {1, 1, 1, 1}
Output: 1

Naive Approach – O(n^2) Time and O(1) Space

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++
// A Simple C++ program to find longest common
// subarray of two binary arrays with same sum
#include<bits/stdc++.h>
using namespace std;

// Returns length of the longest common subarray
// with same sum
int longestCommonSum(vector<bool>& a, vector<bool>& b) {
  
    int res = 0;

    // One by one pick all possible starting points
    // of subarrays
    int n = a.size();
    for (int i = 0; i < n; i++) {
      
        // Initialize sums of current subarrays
        int sum1 = 0, sum2 = 0;

        // Consider all ending points starting with a[i]
        for (int j = i; j < n; j++) {
            sum1 += a[j];
            sum2 += b[j];

            // If sums are the same and current length
            // is more than res, update res
            if (sum1 == sum2) {
               res = max(res, j - i + 1);
            }
        }
    }
    return res;
}

int main() {
    vector<bool> a = {0, 1, 0, 1, 1, 1, 1};
    vector<bool> b = {1, 1, 1, 1, 1, 0, 1};    
    cout << longestCommonSum(a, b);
    return 0;
}
Java Python C# JavaScript PHP

Output
6

Expected Approach 1 – O(n) Time and O(n) Space

The idea is based on the below observations. 

  1. Since there are total n elements, maximum sum is n for both arrays.
  2. The difference between two sums varies from -n to n. So there are total 2n + 1 possible values of difference.
  3. 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 implementation of above algorithm.  

C++
// A O(n) and O(n) extra space C++ program to find
// longest common subarray of two binary arrays with
// same sum
#include<bits/stdc++.h>
using namespace std;

// Returns length of the longest common sum in a[]
// and b[]. Both are of same size n.
int longestCommonSum(vector<bool>& a, vector<bool>& b) {
    int res = 0;

    // Prefix sums of two arrays
    int preSum1 = 0, preSum2 = 0;

    // Create an array to store starting and ending
    // indexes of all possible diff values. diff[i]
    // would store starting and ending points for
    // difference "i-n"
    int n = a.size();
    vector<int> diff(2 * n + 1, -1);

    // Traverse both arrays
    for (int i = 0; i < n; i++) {
      
        // Update prefix sums
        preSum1 += a[i];
        preSum2 += b[i];

        // Compute current diff and index to be used
        // in diff array. Note that diff can be negative
        // and can have minimum value as -n.
        int curr_diff = preSum1 - preSum2;
        int diffIndex = n + curr_diff;

        // If current diff is 0, then there are same number
        // of 1's and 0's so far in both arrays, i.e., (i+1) is
        // maximum length.
        if (curr_diff == 0)
            res = i + 1;

        // If current diff is seen first time, update
        // starting index of diff.
        else if (diff[diffIndex] == -1)
            diff[diffIndex] = i;

        // Current diff is already seen which means 
        // there lies curr_diff = 0 in between
        else {
          
            // Find length of this same sum by 
            // calculating the common span and
            // update result if required
            res = max(res, i - diff[diffIndex]);
        }
    }
    return res;
}

// Driver code
int main() {
    vector<bool> a = {0, 1, 0, 1, 1, 1, 1};
    vector<bool> b = {1, 1, 1, 1, 1, 0, 1};
    cout << longestCommonSum(a, b);
    return 0;
}
Java Python C# JavaScript

Output
6

Expected Approach 2 – Prefix Sum and Hashing – O(n) Time and O(n) Space

  1. Find difference array arr[] such that arr[i] = a[i] – b[i].
  2. Largest subarray with equal number of 0s and 1s in the difference array.
C++
// C++ program to find largest subarray 
// with equal number of 0's and 1's.
#include <bits/stdc++.h>
using namespace std;

// Returns largest common subarray with equal 
// number of 0s and 1s in both a and b.
int longestCommonSum(vector<bool>& a, vector<bool>& b) {
  
    // Find difference between the two
    int n = a.size();
    vector<int> arr(n);
    for (int i = 0; i < n; i++)
        arr[i] = a[i] - b[i];
    
    // Creates an empty hashMap m
    unordered_map<int, int> m;

    int sum = 0;     // Initialize sum of elements
    int max_len = 0; // Initialize result

    // Traverse through the given array
    for (int i = 0; i < n; i++) {
        sum += arr[i];

        // To handle sum=0 at last index
        if (sum == 0)
            max_len = i + 1;

        // If this sum is seen before, 
        // then update max_len if required
        if (m.find(sum) != m.end())
            max_len = max(max_len, i - m[sum]);
      
        else 
            m[sum] = i;
    }

    return max_len;
}

int main() {
    vector<bool> a = {0, 1, 0, 1, 1, 1, 1};
    vector<bool> b = {1, 1, 1, 1, 1, 0, 1};
    cout << longestCommonSum(a, b);
    return 0;
}
Java Python C# JavaScript

Output
6




Next Article
Practice Tags :

Similar Reads

three90RightbarBannerImg