# Count ways to split array into two equal sum subarrays by replacing each array element to 0 once

• Last Updated : 15 Jun, 2021

Given an array arr[] consisting of N integers, the task is to count the number of ways to split the array into two subarrays of equal sum after changing a single array element to 0.

Examples:

Input: arr[] = {1, 2, -1, 3}
Output: 4
Explanation:
Replacing arr by 0, arr[] is modified to {0, 2, -1, 3}. Only 1 possible split is {0, 2} and {-1, 3}.
Replacing arr by 0, arr[] is modified to {1, 0, -1, 3}. No way to split the array.
Replacing arr by 0, arr[] is modified to {1, 2, 0, 3}. The 2 possible splits are {1, 2, 0} and {3}, {1, 2} and {0, 3}.
Replacing arr by 0, arr[] is modified to {1, 2, -1, 0}. Only 1 possible split is {1} and {2, -1, 0}.
Therefore, the total number of ways to split = 1 + 0 + 2 + 1 = 4.

Input: arr[] = {1, 2, 1, 1, 3, 1}
Output: 6
Explanation:
Replacing arr by 0, arr[] is modified to {0, 2, 1, 1, 3, 1}. Only 1 possible split exists.
Replacing arr by 0, arr[] is modified to {1, 0, 1, 1, 3, 1}. No way to split the array.
Replacing arr by 0, arr[] is modified to {1, 2, 0, 1, 3, 1}. Only 1 possible split exists.
Replacing arr by 0, arr[] is modified to {1, 2, 1, 0, 3, 1}. Only 2 possible splits exist.
Replacing arr by 0, arr[] is modified to {1, 2, 1, 1, 0, 1}. Only 1 possible split exists.
Replacing arr by 0, arr[] is modified to {1, 2, 1, 1, 3, 0}. Only 1 possible split exists.
Total number of ways to split is = 1 + 0 + 1 + 2 + 1 + 1 = 6.

Naive Approach: The simplest approach to solve the problem is to traverse the array, convert each array element arr[i] to 0 and count the number of ways to split the modified array into two subarrays with equal sum.

Time Complexity: O(N2)
Auxiliary Space: O(1)

Efficient Approach: To optimize the above approach, the idea is based on the following observations:

Considering two arrays arr1[] and arr2[] with sum of the array elements equal to sum_arr1 and sum_arr2 respectively.
Let dif be the difference between sum_arr1 and sum_arr2, i.e., sum_arr1 – sum_arr2 = dif
Now, sum_arr1 can be made equal to sum_arr2 by performing any one of the two operations:

• Remove an element from arr1[] whose value is equal to dif.
• Remove an element from arr2[] whose value is equal to -dif.

Therefore, the total number of ways to obtain sum_arr1 = sum_arr2 is equal to the count of dif in arr1 + count of (-dif) in arr2.

For every index in the range [0, N – 1], the total number of ways can be obtained by considering the current index as the splitting point, by making any element equal to 0 using the process discussed above. Follow the steps below to solve the problem:

• Initialize a variable count with 0 to store the desired result and prefix_sum the with 0 to store the prefix sum and suffixSum with 0 to store the suffix sum.
• Initialize hashmaps prefixCount and suffixCount to store the count of elements in prefix and suffix arrays.
• Traverse the arr[] and update the frequency of each element in suffixCount.
• Traverse the arr[] over the range [0, N – 1] using variable i.
• Add arr[i] to the prefixCount hashmap and remove it from suffixCount.
• Add arr[i] to prefixSum and set suffixSum to the difference of the total sum of the array and prefixSum.
• Store the difference between the sum of a subarray in variable dif = prefix_sum – suffixSum.
• Store the number of ways to split at ith index in number_of_subarray_at_i_split and is equal to the sum of prefixCount and suffixCount.
• Update the count by adding number_of_subarray_at_i_split to it.
• After the above steps, print the value of count as the result.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// Function to find number of ways to``// split array into 2 subarrays having``// equal sum by changing element to 0 once``int` `countSubArrayRemove(``int` `arr[], ``int` `N)``{``    ``// Stores the count of elements``    ``// in prefix and suffix of``    ``// array elements``    ``unordered_map<``int``, ``int``>``        ``prefix_element_count,``        ``suffix_element_count;` `    ``// Stores the sum of array``    ``int` `total_sum_of_elements = 0;` `    ``// Traverse the array``    ``for` `(``int` `i = N - 1; i >= 0; i--) {` `        ``total_sum_of_elements += arr[i];` `        ``// Increase the frequency of``        ``// current element in suffix``        ``suffix_element_count[arr[i]]++;``    ``}` `    ``// Stores prefix sum upto index i``    ``int` `prefix_sum = 0;` `    ``// Stores sum of suffix of index i``    ``int` `suffix_sum = 0;` `    ``// Stores the desired result``    ``int` `count_subarray_equal_sum = 0;` `    ``// Traverse the array``    ``for` `(``int` `i = 0; i < N; i++) {` `        ``// Modify prefix sum``        ``prefix_sum += arr[i];` `        ``// Add arr[i] to prefix map``        ``prefix_element_count[arr[i]]++;` `        ``// Calculate suffix sum by``        ``// subtracting prefix sum``        ``// from total sum of elements``        ``suffix_sum = total_sum_of_elements``                     ``- prefix_sum;` `        ``// Remove arr[i] from suffix map``        ``suffix_element_count[arr[i]]--;` `        ``// Store the difference``        ``// between the subarrays``        ``int` `difference = prefix_sum``                         ``- suffix_sum;` `        ``// Count number of ways to split``        ``// the array at index i such that``        ``// subarray sums are equal``        ``int` `number_of_subarray_at_i_split``            ``= prefix_element_count[difference]``              ``+ suffix_element_count[-difference];` `        ``// Update the final result``        ``count_subarray_equal_sum``            ``+= number_of_subarray_at_i_split;``    ``}` `    ``// Return the result``    ``return` `count_subarray_equal_sum;``}` `// Driver Code``int` `main()``{``    ``int` `arr[] = { 1, 2, 1, 1, 3, 1 };``    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);` `    ``// Function Call``    ``cout << countSubArrayRemove(arr, N);` `    ``return` `0;``}`

## Java

 `// Java program for the above approach``import` `java.util.*;` `class` `GFG{``    ` `// Function to find number of ways to``// split array into 2 subarrays having``// equal sum by changing element to 0 once``static` `int` `countSubArrayRemove(``int` `[]arr, ``int` `N)``{``    ` `    ``// Stores the count of elements``    ``// in prefix and suffix of``    ``// array elements``    ``HashMap prefix_element_count = ``new` `HashMap();``    ``HashMap suffix_element_count = ``new` `HashMap();` `    ``// Stores the sum of array``    ``int` `total_sum_of_elements = ``0``;` `    ``// Traverse the array``    ``for``(``int` `i = N - ``1``; i >= ``0``; i--)``    ``{``        ``total_sum_of_elements += arr[i];` `        ``// Increase the frequency of``        ``// current element in suffix``        ``if` `(!suffix_element_count.containsKey(arr[i]))``            ``suffix_element_count.put(arr[i], ``1``);``        ``else``            ``suffix_element_count.put(arr[i],``              ``suffix_element_count.get(arr[i]) + ``1``);``    ``}` `    ``// Stores prefix sum upto index i``    ``int` `prefix_sum = ``0``;` `    ``// Stores sum of suffix of index i``    ``int` `suffix_sum = ``0``;` `    ``// Stores the desired result``    ``int` `count_subarray_equal_sum = ``0``;` `    ``// Traverse the array``    ``for``(``int` `i = ``0``; i < N; i++)``    ``{``        ` `        ``// Modify prefix sum``        ``prefix_sum += arr[i];` `        ``// Add arr[i] to prefix map``       ``if` `(!prefix_element_count.containsKey(arr[i]))``           ``prefix_element_count.put(arr[i], ``1``);``       ``else``           ``prefix_element_count.put(arr[i],``           ``prefix_element_count.get(arr[i]) + ``1``);` `        ``// Calculate suffix sum by``        ``// subtracting prefix sum``        ``// from total sum of elements``        ``suffix_sum = total_sum_of_elements -``                     ``prefix_sum;` `        ``// Remove arr[i] from suffix map``        ``if` `(!suffix_element_count.containsKey(arr[i]))``            ``suffix_element_count.put(arr[i], ``0``);``        ``else``            ``suffix_element_count.put(arr[i],``            ``suffix_element_count.get(arr[i]) - ``1``);` `        ``// Store the difference``        ``// between the subarrays``        ``int` `difference = prefix_sum -``                         ``suffix_sum;` `        ``// Count number of ways to split``        ``// the array at index i such that``        ``// subarray sums are equal``        ``int` `number_of_subarray_at_i_split = ``0``;``        ``if` `(prefix_element_count.containsKey(difference))``            ``number_of_subarray_at_i_split =``            ``prefix_element_count.get(difference);``        ``if` `(suffix_element_count.containsKey(-difference))``            ``number_of_subarray_at_i_split +=``            ``suffix_element_count.get(-difference);` `        ``// Update the final result``        ``count_subarray_equal_sum +=``        ``number_of_subarray_at_i_split;``    ``}` `    ``// Return the result``    ``return` `count_subarray_equal_sum;``}  ` `// Driver Code``public` `static` `void` `main(String args[])``{``    ``int` `[]arr = { ``1``, ``2``, ``1``, ``1``, ``3``, ``1` `};``    ``int` `N = arr.length;``    ` `    ``// Function Call``    ``System.out.println(countSubArrayRemove(arr, N));``}``}` `// This code is contributed by Stream_Cipher`

## Python3

 `# Python3 program for the above approach` `# Function to find number of ways to``# split array into 2 subarrays having``# equal sum by changing element to 0 once``def` `countSubArrayRemove(arr, N):``    ` `    ``# Stores the count of elements``    ``# in prefix and suffix of``    ``# array elements``    ``prefix_element_count ``=` `{}``    ``suffix_element_count ``=` `{}` `    ``# Stores the sum of array``    ``total_sum_of_elements ``=` `0` `    ``# Traverse the array``    ``i ``=` `N ``-` `1``    ``while` `(i >``=` `0``):``        ``total_sum_of_elements ``+``=` `arr[i]` `        ``# Increase the frequency of``        ``# current element in suffix``        ``suffix_element_count[arr[i]] ``=` `suffix_element_count.get(``            ``arr[i], ``0``) ``+` `1``            ` `        ``i ``-``=` `1` `    ``# Stores prefix sum upto index i``    ``prefix_sum ``=` `0` `    ``# Stores sum of suffix of index i``    ``suffix_sum ``=` `0` `    ``# Stores the desired result``    ``count_subarray_equal_sum ``=` `0` `    ``# Traverse the array``    ``for` `i ``in` `range``(N):``        ` `        ``# Modify prefix sum``        ``prefix_sum ``+``=` `arr[i]` `        ``# Add arr[i] to prefix map``        ``prefix_element_count[arr[i]] ``=` `prefix_element_count.get(``            ``arr[i], ``0``) ``+` `1` `        ``# Calculate suffix sum by``        ``# subtracting prefix sum``        ``# from total sum of elements``        ``suffix_sum ``=` `total_sum_of_elements ``-` `prefix_sum` `        ``# Remove arr[i] from suffix map``        ``suffix_element_count[arr[i]] ``=` `suffix_element_count.get(``            ``arr[i], ``0``) ``-` `1` `        ``# Store the difference``        ``# between the subarrays``        ``difference ``=` `prefix_sum ``-` `suffix_sum` `        ``# Count number of ways to split``        ``# the array at index i such that``        ``# subarray sums are equal``        ``number_of_subarray_at_i_split ``=` `(prefix_element_count.get(``                                             ``difference, ``0``) ``+``                                         ``suffix_element_count.get(``                                            ``-``difference, ``0``))` `        ``# Update the final result``        ``count_subarray_equal_sum ``+``=` `number_of_subarray_at_i_split` `    ``# Return the result``    ``return` `count_subarray_equal_sum` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``    ` `    ``arr ``=` `[ ``1``, ``2``, ``1``, ``1``, ``3``, ``1` `]``    ``N ``=`  `len``(arr)` `    ``# Function Call``    ``print``(countSubArrayRemove(arr, N))``    ` `# This code is contributed by SURENDRA_GANGWAR`

## C#

 `// C# program for the above approach``using` `System;``using` `System.Collections.Generic;` `class` `GFG{``    ` `// Function to find number of ways to``// split array into 2 subarrays having``// equal sum by changing element to 0 once``static` `int` `countSubArrayRemove(``int` `[]arr, ``int` `N)``{``    ` `    ``// Stores the count of elements``    ``// in prefix and suffix of``    ``// array elements``    ``Dictionary<``int``,``               ``int``> prefix_element_count = ``new` `Dictionary<``int``,``                                                          ``int``> ();``    ``Dictionary<``int``,``               ``int` `>suffix_element_count = ``new` `Dictionary <``int``,``                                                           ``int``>();` `    ``// Stores the sum of array``    ``int` `total_sum_of_elements = 0;` `    ``// Traverse the array``    ``for``(``int` `i = N - 1; i >= 0; i--)``    ``{``        ``total_sum_of_elements += arr[i];` `        ``// Increase the frequency of``        ``// current element in suffix``        ``if` `(!suffix_element_count.ContainsKey(arr[i]))``            ``suffix_element_count[arr[i]] = 1;``        ``else``            ``suffix_element_count[arr[i]]++;``    ``}` `    ``// Stores prefix sum upto index i``    ``int` `prefix_sum = 0;` `    ``// Stores sum of suffix of index i``    ``int` `suffix_sum = 0;` `    ``// Stores the desired result``    ``int` `count_subarray_equal_sum = 0;` `    ``// Traverse the array``    ``for``(``int` `i = 0; i < N; i++)``    ``{``        ` `        ``// Modify prefix sum``        ``prefix_sum += arr[i];` `        ``// Add arr[i] to prefix map``       ``if` `(!prefix_element_count.ContainsKey(arr[i]))``           ``prefix_element_count[arr[i]] = 1;``       ``else``           ``prefix_element_count[arr[i]]++;` `        ``// Calculate suffix sum by``        ``// subtracting prefix sum``        ``// from total sum of elements``        ``suffix_sum = total_sum_of_elements -``                     ``prefix_sum;` `        ``// Remove arr[i] from suffix map``        ``if` `(!suffix_element_count.ContainsKey(arr[i]))``            ``suffix_element_count[arr[i]] = 0;``        ``else``            ``suffix_element_count[arr[i]]-= 1;` `        ``// Store the difference``        ``// between the subarrays``        ``int` `difference = prefix_sum -``                         ``suffix_sum;` `        ``// Count number of ways to split``        ``// the array at index i such that``        ``// subarray sums are equal``        ``int` `number_of_subarray_at_i_split = 0;``        ``if` `(prefix_element_count.ContainsKey(difference))``            ``number_of_subarray_at_i_split``            ``= prefix_element_count[difference];``        ``if` `(suffix_element_count.ContainsKey(-difference))``            ``number_of_subarray_at_i_split``            ``+= suffix_element_count[-difference];` `        ``// Update the final result``        ``count_subarray_equal_sum``            ``+= number_of_subarray_at_i_split;``    ``}` `    ``// Return the result``    ``return` `count_subarray_equal_sum;``}` `// Driver Code``public` `static` `void` `Main(``string` `[]args)``{``    ``int` `[]arr = { 1, 2, 1, 1, 3, 1 };``    ``int` `N = arr.Length;` `    ``// Function Call``    ``Console.Write(countSubArrayRemove(arr, N));``}``}` `// This code is contributed by chitranayal`

## Javascript

 ``

Output:

`6`

Time Complexity: O(N)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up