# Count ways to split array into two equal sum subarrays by changing sign of any one array element

• Difficulty Level : Hard
• Last Updated : 24 Jun, 2021

Given an array arr[] consisting of N integers, the task is to count ways to split array into two subarrays of equal sum by changing the sign of any one array element.

Examples:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Input: arr[] = {2, 2, -3, 3}
Output: 2
Explanation:
Changing arr = 2 to arr = -2, the array becomes {-2, 2, -3, 3}. Only 1 possible split is {-2, 2} and {-3, 3}.
Changing arr = 2 to arr = -2, the array becomes {2, -2, -3, 3}. Only 1 possible split is {-2, 2} and {-3, 3}.
Changing arr = -3 to arr = 3, the array becomes {2, 2, 3, 3}. No way to split the array.
Changing arr = 3 to arr = -3, the array becomes {2, 2, -3, -3}. No way to split the array.
Therefore, the total number of ways to split = 1 + 1 + 0 + 0 = 2.

Input: arr[] = {2, 2, 1, -3, 3}
Output: 0

Naive Approach: The simplest approach to solve the problem is to traverse the array and change the sign of every array element one by one and count the number of ways to split array into two equal sum subarrays for every alteration. Finally, print the sum of all possible ways.
Time Complexity: O(N2)
Auxiliary Space: O(1)

Efficient Approach: To optimize the above approach, the idea is to store the prefix sum and suffix sum for every array indices to find the sum of the splitter subarrays in O(1) computational complexity. Follow the steps below to solve the problem:

• Initialize a variable, say count, to store the number of ways to split the array.
• Initialize two variables, say prefixSum and suffixSum, with 0, to store the prefix and suffix sums of both the arrays.
• Initialize two Maps prefixCount and suffixCount to store the count of elements in prefix and suffix arrays.
• Traverse the array arr[] and update the frequency of each element in suffixCount.
• Traverse the array arr[] and perform the following steps:
• Insert arr[i] into the prefixCount map 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 the subarrays, i.e. prefixSum – suffixSum in a variable, say diff.
• The count of ways to split at the ith index is calculated by:
• If diff is odd, then the array cannot be split.
• If diff is even, then add the value (prefixCount + suffixCount[ -diff / 2]) to count.
• After completing the above steps, the value of count gives the total count of possible splits.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// Function to count ways of splitting``// the array in two subarrays of equal``// sum by changing sign of any 1 element``int` `countSubArraySignChange(``int` `arr[], ``int` `N)``{``    ``// Stores the count of elements``    ``// in prefix and suffix of array``    ``unordered_map<``int``, ``int``> prefixCount;``    ``unordered_map<``int``, ``int``> suffixCount;` `    ``// Stores the total sum of array``    ``int` `total = 0;` `    ``// Traverse the array``    ``for` `(``int` `i = N - 1; i >= 0; i--) {` `        ``total += arr[i];` `        ``// Increase the frequency of``        ``// current element in suffix``        ``suffixCount[arr[i]]++;``    ``}` `    ``// Stores prefix sum upto``    ``// an index``    ``int` `prefixSum = 0;` `    ``// Stores sum of suffix``    ``// from an index``    ``int` `suffixSum = 0;` `    ``// Stores the count of ways to``    ``// split the array in 2 subarrays``    ``// having equal sum``    ``int` `count = 0;` `    ``// Traverse the array``    ``for` `(``int` `i = 0; i < N - 1; i++) {` `        ``// Modify prefix sum``        ``prefixSum += arr[i];` `        ``// Add arr[i] to prefix Map``        ``prefixCount[arr[i]]++;` `        ``// Calculate suffix sum by``        ``// subtracting prefix sum``        ``// from total sum of elements``        ``suffixSum = total - prefixSum;` `        ``// Remove arr[i] from suffix Map``        ``suffixCount[arr[i]]--;` `        ``// Store the difference``        ``// between the subarrays``        ``int` `diff = prefixSum - suffixSum;` `        ``// Check if diff is even or not``        ``if` `(diff % 2 == 0) {` `            ``// Count number of ways to``            ``// split array at index i such``            ``// that subarray sums are same``            ``int` `x = prefixCount``                    ``+ suffixCount[-diff / 2];` `            ``// Update the count``            ``count = count + x;``        ``}``    ``}` `    ``// Return the count``    ``return` `count;``}` `// Driver Code``int` `main()``{``    ``int` `arr[] = { 2, 2, -3, 3 };``    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);` `    ``// Function Call``    ``cout << countSubArraySignChange(arr, N);` `    ``return` `0;``}`

## Java

 `// Java program for the above approach``import` `java.util.*;``class` `GFG{` `// Function to count ways of splitting``// the array in two subarrays of equal``// sum by changing sign of any 1 element``static` `int` `countSubArraySignChange(``int` `arr[], ``int` `N)``{``  ` `    ``// Stores the count of elements``    ``// in prefix and suffix of array``    ``HashMap prefixCount = ``new` `HashMap();``    ``HashMap suffixCount = ``new` `HashMap();` `    ``// Stores the total sum of array``    ``int` `total = ``0``;` `    ``// Traverse the array``    ``for` `(``int` `i = N - ``1``; i >= ``0``; i--)``    ``{` `        ``total += arr[i];` `        ``// Increase the frequency of``        ``// current element in suffix``        ``if``(suffixCount.containsKey(arr[i])){``            ``suffixCount.put(arr[i], suffixCount.get(arr[i]) + ``1``);``        ``}``        ``else``{``            ``suffixCount.put(arr[i], ``1``);``        ``}``    ``}` `    ``// Stores prefix sum upto``    ``// an index``    ``int` `prefixSum = ``0``;` `    ``// Stores sum of suffix``    ``// from an index``    ``int` `suffixSum = ``0``;` `    ``// Stores the count of ways to``    ``// split the array in 2 subarrays``    ``// having equal sum``    ``int` `count = ``0``;` `    ``// Traverse the array``    ``for` `(``int` `i = ``0``; i < N - ``1``; i++)``    ``{` `        ``// Modify prefix sum``        ``prefixSum += arr[i];` `        ``// Add arr[i] to prefix Map``        ``if``(prefixCount.containsKey(arr[i]))``        ``{``            ``prefixCount.put(arr[i], prefixCount.get(arr[i])+``1``);``        ``}``        ``else``        ``{``            ``prefixCount.put(arr[i], ``1``);``        ``}` `        ``// Calculate suffix sum by``        ``// subtracting prefix sum``        ``// from total sum of elements``        ``suffixSum = total - prefixSum;` `        ``// Remove arr[i] from suffix Map``        ``if``(suffixCount.containsKey(arr[i]))``        ``{``            ``suffixCount.put(arr[i], suffixCount.get(arr[i]) - ``1``);``        ``}` `        ``// Store the difference``        ``// between the subarrays``        ``int` `diff = prefixSum - suffixSum;` `        ``// Check if diff is even or not``        ``if` `(diff % ``2` `== ``0``)``        ``{` `            ``// Count number of ways to``            ``// split array at index i such``            ``// that subarray sums are same``            ``int` `x = (prefixCount.containsKey(diff / ``2``)?prefixCount.get(diff / ``2``):``0``)``                    ``+ (suffixCount.containsKey(-diff / ``2``)?suffixCount.get(-diff / ``2``):``0``);` `            ``// Update the count``            ``count = count + x;``        ``}``    ``}` `    ``// Return the count``    ``return` `count;``}` `// Driver Code``public` `static` `void` `main(String[] args)``{``    ``int` `arr[] = { ``2``, ``2``, -``3``, ``3` `};``    ``int` `N = arr.length;` `    ``// Function Call``    ``System.out.print(countSubArraySignChange(arr, N));``}``}` `// This code is contributed by 29AjayKumar`

## Python3

 `# Python3 program for the above approach` `# Function to count ways of spliting``# the array in two subarrays of equal``# sum by changing sign of any 1 element``def` `countSubArraySignChange(arr, N):``    ` `    ``# Stores the count of elements``    ``# in prefix and suffix of array``    ``prefixCount ``=` `{}``    ``suffixCount ``=` `{}` `    ``# Stores the total sum of array``    ``total ``=` `0` `    ``# Traverse the array``    ``for` `i ``in` `range``(N ``-` `1``, ``-``1``, ``-``1``):` `        ``total ``+``=` `arr[i]` `        ``# Increase the frequency of``        ``# current element in suffix``        ``suffixCount[arr[i]] ``=` `suffixCount.get(arr[i], ``0``) ``+` `1` `    ``# Stores prefix sum upto``    ``# an index``    ``prefixSum ``=` `0` `    ``# Stores sum of suffix``    ``# from an index``    ``suffixSum ``=` `0` `    ``# Stores the count of ways to``    ``# split the array in 2 subarrays``    ``# having equal sum``    ``count ``=` `0` `    ``# Traverse the array``    ``for` `i ``in` `range``(N ``-` `1``):` `        ``# Modify prefix sum``        ``prefixSum ``+``=` `arr[i]` `        ``# Add arr[i] to prefix Map``        ``prefixCount[arr[i]] ``=` `prefixCount.get(arr[i], ``0``) ``+` `1` `        ``# Calculate suffix sum by``        ``# subtracting prefix sum``        ``# from total sum of elements``        ``suffixSum ``=` `total ``-` `prefixSum` `        ``# Remove arr[i] from suffix Map``        ``suffixCount[arr[i]] ``-``=` `1` `        ``# Store the difference``        ``# between the subarrays``        ``diff ``=` `prefixSum ``-` `suffixSum` `        ``# Check if diff is even or not``        ``if` `(diff ``%` `2` `=``=` `0``):` `            ``# Count number of ways to``            ``# split array at index i such``            ``# that subarray sums are same``            ``y, z ``=` `0``, ``0``            ``if` `-``diff``/``/``2` `in` `suffixCount:``                ``y ``=` `suffixCount[``-``dff``/``/``2``]``            ``if` `diff``/``/``2` `in` `prefixCount:``                ``z ``=` `prefixCount``            ``x ``=` `z``+` `y` `            ``# Update the count``            ``count ``=` `count ``+` `x` `    ``# Return the count``    ``return` `count` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``    ``arr``=``[``2``, ``2``, ``-``3``, ``3``]``    ``N ``=` `len``(arr)` `    ``# Function Call``    ``print``(countSubArraySignChange(arr, N))` `    ``# This code is contributed by mohit kumar 29`

## C#

 `// C# program for the above approach``using` `System;``using` `System.Collections.Generic;` `class` `GFG{` `  ``// Function to count ways of splitting``  ``// the array in two subarrays of equal``  ``// sum by changing sign of any 1 element``  ``static` `int` `countSubArraySignChange(``int` `[]arr, ``int` `N)``  ``{` `    ``// Stores the count of elements``    ``// in prefix and suffix of array``    ``Dictionary<``int``,``int``> prefixCount = ``new` `Dictionary<``int``,``int``>();``    ``Dictionary<``int``,``int``> suffixCount = ``new` `Dictionary<``int``,``int``>();` `    ``// Stores the total sum of array``    ``int` `total = 0;` `    ``// Traverse the array``    ``for` `(``int` `i = N - 1; i >= 0; i--)``    ``{` `      ``total += arr[i];` `      ``// Increase the frequency of``      ``// current element in suffix``      ``if``(suffixCount.ContainsKey(arr[i])){``        ``suffixCount[arr[i]] = suffixCount[arr[i]] + 1;``      ``}``      ``else``{``        ``suffixCount.Add(arr[i], 1);``      ``}``    ``}` `    ``// Stores prefix sum upto``    ``// an index``    ``int` `prefixSum = 0;` `    ``// Stores sum of suffix``    ``// from an index``    ``int` `suffixSum = 0;` `    ``// Stores the count of ways to``    ``// split the array in 2 subarrays``    ``// having equal sum``    ``int` `count = 0;` `    ``// Traverse the array``    ``for` `(``int` `i = 0; i < N - 1; i++)``    ``{` `      ``// Modify prefix sum``      ``prefixSum += arr[i];` `      ``// Add arr[i] to prefix Map``      ``if``(prefixCount.ContainsKey(arr[i]))``      ``{``        ``prefixCount[arr[i]] = prefixCount[arr[i]] + 1;``      ``}``      ``else``      ``{``        ``prefixCount.Add(arr[i], 1);``      ``}` `      ``// Calculate suffix sum by``      ``// subtracting prefix sum``      ``// from total sum of elements``      ``suffixSum = total - prefixSum;` `      ``// Remove arr[i] from suffix Map``      ``if``(suffixCount.ContainsKey(arr[i]))``      ``{``        ``suffixCount[arr[i]] = suffixCount[arr[i]] - 1;``      ``}` `      ``// Store the difference``      ``// between the subarrays``      ``int` `diff = prefixSum - suffixSum;` `      ``// Check if diff is even or not``      ``if` `(diff % 2 == 0)``      ``{` `        ``// Count number of ways to``        ``// split array at index i such``        ``// that subarray sums are same``        ``int` `x = (prefixCount.ContainsKey(diff / 2)?prefixCount:0)``          ``+ (suffixCount.ContainsKey(-diff / 2)?suffixCount[-diff / 2]:0);` `        ``// Update the count``        ``count = count + x;``      ``}``    ``}` `    ``// Return the count``    ``return` `count;``  ``}` `  ``// Driver Code``  ``public` `static` `void` `Main(String[] args)``  ``{``    ``int` `[]arr = { 2, 2, -3, 3 };``    ``int` `N = arr.Length;` `    ``// Function Call``    ``Console.Write(countSubArraySignChange(arr, N));``  ``}``}`  `// This code is contributed by 29AjayKumar`

## Javascript

 ``
Output:
`2`

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

My Personal Notes arrow_drop_up