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[0] by 0, arr[] is modified to {0, 2, -1, 3}. Only 1 possible split is {0, 2} and {-1, 3}.
Replacing arr[1] by 0, arr[] is modified to {1, 0, -1, 3}. No way to split the array.
Replacing arr[2] 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[3] 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[0] by 0, arr[] is modified to {0, 2, 1, 1, 3, 1}. Only 1 possible split exists.
Replacing arr[1] by 0, arr[] is modified to {1, 0, 1, 1, 3, 1}. No way to split the array.
Replacing arr[2] by 0, arr[] is modified to {1, 2, 0, 1, 3, 1}. Only 1 possible split exists.
Replacing arr[3] by 0, arr[] is modified to {1, 2, 1, 0, 3, 1}. Only 2 possible splits exist.
Replacing arr[4] by 0, arr[] is modified to {1, 2, 1, 1, 0, 1}. Only 1 possible split exists.
Replacing arr[5] 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[diff][/diff] 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 <bits/stdc++.h>
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[0]);
// 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<Integer,
Integer> prefix_element_count = new HashMap<Integer,
Integer>();
HashMap<Integer,
Integer> suffix_element_count = new HashMap<Integer,
Integer>();
// 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
<script>
// Javascript 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
function countSubArrayRemove(arr, N)
{
// Stores the count of elements
// in prefix and suffix of
// array elements
let prefix_element_count = new Map();
let suffix_element_count = new Map();
// Stores the sum of array
let total_sum_of_elements = 0;
// Traverse the array
for(let i = N - 1; i >= 0; i--)
{
total_sum_of_elements += arr[i];
// Increase the frequency of
// current element in suffix
if (!suffix_element_count.has(arr[i]))
suffix_element_count.set(arr[i], 1);
else
suffix_element_count.set(arr[i],
suffix_element_count.get(arr[i]) + 1);
}
// Stores prefix sum upto index i
let prefix_sum = 0;
// Stores sum of suffix of index i
let suffix_sum = 0;
// Stores the desired result
let count_subarray_equal_sum = 0;
// Traverse the array
for(let i = 0; i < N; i++)
{
// Modify prefix sum
prefix_sum += arr[i];
// Add arr[i] to prefix map
if (!prefix_element_count.has(arr[i]))
prefix_element_count.set(arr[i], 1);
else
prefix_element_count.set(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.has(arr[i]))
suffix_element_count.set(arr[i], 0);
else
suffix_element_count.set(arr[i],
suffix_element_count.get(arr[i]) - 1);
// Store the difference
// between the subarrays
let difference = prefix_sum -
suffix_sum;
// Count number of ways to split
// the array at index i such that
// subarray sums are equal
let number_of_subarray_at_i_split = 0;
if (prefix_element_count.has(difference))
number_of_subarray_at_i_split =
prefix_element_count.get(difference);
if (suffix_element_count.has(-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
let arr = [ 1, 2, 1, 1, 3, 1 ];
let N = arr.length;
// Function Call
document.write(countSubArrayRemove(arr, N));
// This code is contributed by avanitrachhadiya2155
</script>
Time Complexity: O(N)
Auxiliary Space: O(N)
Similar Reads
Count ways to split array into two equal sum subarrays by changing sign of any one array element 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: Input: arr[] = {2, 2, -3, 3}Output: 2Explanation:Changing arr[0] = 2 to arr[0] = -2, the array becomes {-2, 2, -3, 3}. Only
11 min read
Count ways to split array into two subarrays with equal GCD Given an array, arr[] of size N, the task is to count the number of ways to split given array elements into two subarrays such that GCD of both the subarrays are equal. Examples: Input: arr[] = {8, 4, 4, 8, 12} Output: 2 Explanation: Possible ways to split the array two groups of equal GCD are: { {{
8 min read
Count of ways to split an Array into three contiguous Subarrays having increasing Sum Given an array arr[] consisting of non-negative integers, the task is to find the number of ways to split the array into three non-empty contiguous subarrays such that their respective sum of elements are in increasing order. Examples: Input: arr[] = {2, 3, 1, 7} Output: 2 Explanation: {{2}, {3, 1},
7 min read
For each element in 1st array count elements less than or equal to it in 2nd array | Set 2 Given two unsorted arrays arr1[] and arr2[]. They may contain duplicates. For each element in arr1[] count elements less than or equal to it in array arr2[]. Examples: Input : arr1[] = [1, 2, 3, 4, 7, 9] arr2[] = [0, 1, 2, 1, 1, 4] Output : [4, 5, 5, 6, 6, 6] Explanation: There are 4 elements less t
13 min read
Count ways to split array into three non-empty subarrays having equal Bitwise XOR values Given an array arr[] consisting of N non-negative integers, the task is to count the number of ways to split the array into three different non-empty subarrays such that Bitwise XOR of each subarray is equal. Examples: Input: arr[] = {7, 0, 5, 2, 7} Output: 2Explanation: All possible ways are:{{7},
9 min read
Number of times an array can be partitioned repetitively into two subarrays with equal sum Given an array arr[] of size N, the task is to find the number of times the array can be partitioned repetitively into two subarrays such that the sum of the elements of both the subarrays is the same. Examples: Input: arr[] = { 2, 2, 2, 2 } Output: 3 Explanation: 1. Make the first partition after i
8 min read