 GeeksforGeeks App
Open App Browser
Continue

# Count of possible arrays from prefix-sum and suffix-sum arrays

Given 2*N integers which are elements of a prefix and suffix array(in shuffled order) of an array of size N, the task is to find the no of possible array’s of the size N which can be made from these elements
Examples:

Input: arr[] = {5, 2, 3, 5}
Output:
Explanation:
1st array can be : {2, 3}
Its prefix array:{2, 5}
Its suffix array:{5, 3}
2nd array can be : {3, 2}
Its prefix array : {3, 5}
Its suffix array : {5, 2}
Input: arr[] = {-1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0}
Output: 80

Approach:

• One insight which can be drawn is that if the sum of all elements of the given array is divided by n+1, then the last and the first element of a prefix and suffix array is obtained respectively.
• This conclusion can be drawn by observing the elements of the prefix and suffix array. The sum of 1st element of prefix array and 2nd element of suffix array is equal to the sum of 2nd element of prefix array and 3rd element of suffix array(if there is a third element in the suffix array) and so on. • In the image, the first array is the given array, the second is the prefix array and the third is suffix array.
• The sum of these pairs is equal to the sum of all elements of the array to be found.
• If it is assumed that the sum of the pairs is s1 and the sum of all prefix and suffix elements is s then:
s1 * (n-1) + 2 * s1 = s
s1 = s / (n+1)
where s1 is the last element of prefix array and 1st element of suffix array.
• Now, all other pairs whose sum will be equal to s1 need to be found which can be done using hash maps.
• If these pairs are shuffled linearly along with the array then we can get the answer as
(n-1)! / (k1! * k2! … kr!)
where k1, k2 … kr are the number of similar pairs
• Each pair can also be interchanged among itself in the prefix and the suffix array(If the elements of pair are not equal) so the answer becomes
(n-1)! * (2^p) / (k1!*k2!…kr!)
where p is the no of distinct pairs in the array whose sum is equal to s1.

Below is the implementation of the above approach.

## C++

 `// C++ implementation of the above approach``#include ``using` `namespace` `std;` `// Function to find power of``// a number.``int` `power(``int` `a, ``int` `b)``{``    ``int` `result = 1;``    ``while` `(b > 0) {``        ``if` `(b % 2 == 1) {``            ``result = result * a;``        ``}``        ``a = a * a;``        ``b = b / 2;``    ``}``    ``return` `result;``}` `// Function to find``// factorial of a number.``int` `factorial(``int` `n)``{``    ``int` `fact = 1;``    ``for` `(``int` `i = 1; i <= n; i++) {``        ``fact = fact * i;``    ``}``    ``return` `fact;``}` `// Function to print no of arrays``void` `findNoOfArrays(``int``* a, ``int` `n)``{``    ``// c variable counts the no of pairs``    ``int` `sum = 0, s1, c = 0;` `    ``// Map to store the frequency``    ``// of each element``    ``map<``int``, ``int``> mp;` `    ``for` `(``int` `i = 0; i < 2 * n; i++) {``        ``mp[a[i]]++;` `        ``// Sum of all elements of the array``        ``sum = sum + a[i];``    ``}` `    ``// Variable to check if it is``    ``// possible to make any array``    ``bool` `isArrayPossible = ``true``;``    ``int` `ans = factorial(n - 1);` `    ``// First element of suffix array``    ``// and the last element of prefix array``    ``s1 = sum / (n + 1);` `    ``// Check if the element exists in the map``    ``if` `(mp[s1] >= 2) {``        ``mp[s1] = mp[s1] - 2;``    ``}``    ``else` `{``        ``isArrayPossible = ``false``;``    ``}``    ``if` `(isArrayPossible) {``        ``for` `(``auto` `i : mp) {` `            ``// If elements of any pair are equal``            ``// and their frequency is not divisible by 2``            ``// update the isArrayPossible variable``            ``// to false and break through the loop` `            ``if` `(i.first == s1 - i.first) {``                ``if` `(mp[i.first] % 2 != 0) {``                    ``isArrayPossible = ``false``;``                    ``break``;``                ``}``            ``}` `            ``// If elements of any pair are not equal``            ``// and their frequency is not same``            ``// update the isArrayPossible variable``            ``// to false and break through the loop` `            ``if` `(i.first != s1 - i.first) {``                ``if` `(mp[i.first]``                    ``!= mp[s1 - i.first]) {``                    ``isArrayPossible = ``false``;``                    ``break``;``                ``}``            ``}``            ``// Check if frequency is greater than zero``            ``if` `(i.second > 0) {``                ``if` `(i.first != s1 - i.first) {``                    ``// update the count of pairs` `                    ``c = c + i.second;` `                    ``// Multiply the answer by``                    ``// 2^(frequency of pairs) since``                    ``// the elements of the pair are``                    ``// not the same in this condition` `                    ``ans = ans * power(2, i.second);` `                    ``// Divide the answer by the factorial``                    ``// of no of similar pairs` `                    ``ans = ans / factorial(i.second);` `                    ``// Make frequency of both these elements 0` `                    ``mp[i.first] = 0;``                    ``mp[s1 - i.first] = 0;``                ``}``                ``if` `(i.first == s1 - i.first) {``                    ``// Update the count of pairs` `                    ``c = c + i.second / 2;` `                    ``// Divide the answer by the factorial``                    ``// of no. of similar pairs` `                    ``ans = ans / factorial(i.second / 2);` `                    ``// Make frequency of this element 0``                    ``mp[i.first] = 0;``                ``}``            ``}``        ``}``    ``}` `    ``// Check if it is possible to make the``    ``// array and there are n-1 pairs``    ``// whose sum will be equal to s1``    ``if` `(c < n - 1 || isArrayPossible == ``false``) {``        ``cout << ``"0"` `<< endl;``    ``}``    ``else` `{``        ``cout << ans << endl;``    ``}``}` `// Driver code``int` `main()``{``    ``int` `arr1[] = { 5, 2, 3, 5 };``    ``int` `n1 = ``sizeof``(arr1) / ``sizeof``(arr1);` `    ``// Function calling``    ``findNoOfArrays(arr1, n1 / 2);` `    ``int` `arr2[] = { -1, -1, -1, 0, 1, 0,``                   ``1, 0, 1, 0, 0, 0 };``    ``int` `n2 = ``sizeof``(arr2) / ``sizeof``(arr2);``    ``findNoOfArrays(arr2, n2 / 2);``    ``return` `0;``}`

## Java

 `// Java implementation of the above approach``import` `java.util.*;` `class` `GFG{``    ` `// Function to find power of``// a number.``static` `int` `power(``int` `a, ``int` `b)``{``    ``int` `result = ``1``;``    ``while` `(b > ``0``) {``        ``if` `(b % ``2` `== ``1``) {``            ``result = result * a;``        ``}``        ``a = a * a;``        ``b = b / ``2``;``    ``}``    ``return` `result;``}` `// Function to find``// factorial of a number.``static` `int` `factorial(``int` `n)``{``    ``int` `fact = ``1``;``    ``for` `(``int` `i = ``1``; i <= n; i++) {``        ``fact = fact * i;``    ``}``    ``return` `fact;``}` `// Function to print no of arrays``static` `void` `findNoOfArrays(``int``[] a, ``int` `n)``{``    ``// c variable counts the no of pairs``    ``int` `sum = ``0``, s1, c = ``0``;` `    ``// Map to store the frequency``    ``// of each element``    ``HashMap mp = ``new` `HashMap();        ` `    ``for` `(``int` `i = ``0``; i < ``2` `* n; i++) {``        ``if``(mp.get(a[i])==``null``)``          ``mp.put(a[i], ``1``);``        ``else``          ``mp.put(a[i], mp.get(a[i]) + ``1``);` `        ``// Sum of all elements of the array``        ``sum = sum + a[i];``    ``}` `    ``// Variable to check if it is``    ``// possible to make any array``    ``boolean` `isArrayPossible = ``true``;``    ``int` `ans = factorial(n - ``1``);` `    ``// First element of suffix array``    ``// and the last element of prefix array``    ``s1 = sum / (n + ``1``);` `    ``// Check if the element exists in the map``    ``if` `(mp.get(s1) >= ``2``) {``        ``mp.replace(s1, mp.get(s1) - ``2``);``    ``}``    ``else` `{``        ``isArrayPossible = ``false``;``    ``}``    ``if` `(isArrayPossible) {``        ``for` `(Map.Entry m:mp.entrySet()) {` `            ``// If elements of any pair are equal``            ``// and their frequency is not divisible by 2``            ``// update the isArrayPossible variable``            ``// to false and break through the loop` `            ``if` `(m.getKey() == s1-m.getKey()) {``                ``if` `(mp.get(m.getKey()) % ``2` `!= ``0``) {``                    ``isArrayPossible = ``false``;``                    ``break``;``                ``}``            ``}` `            ``// If elements of any pair are not equal``            ``// and their frequency is not same``            ``// update the isArrayPossible variable``            ``// to false and break through the loop` `            ``if` `(m.getKey() != s1 - m.getKey()) {``                ``if` `(mp.get(m.getKey())``                    ``!= mp.get(s1 - m.getKey())) {``                    ``isArrayPossible = ``false``;``                    ``break``;``                ``}``            ``}``            ``// Check if frequency is greater than zero``            ``if` `(m.getValue() > ``0``) {``                ``if` `(m.getKey() != s1 - m.getKey()) {``                    ``// update the count of pairs` `                    ``c = c + m.getValue();` `                    ``// Multiply the answer by``                    ``// 2^(frequency of pairs) since``                    ``// the elements of the pair are``                    ``// not the same in this condition``                    ``ans = ans * power(``2``, m.getValue());` `                    ``// Divide the answer by the factorial``                    ``// of no of similar pairs``                    ``ans = ans / factorial(m.getValue());` `                    ``// Make frequency of both these elements 0``                    ``mp.replace(m.getKey(),``0``);``                    ``mp.replace(s1 - m.getKey(),``0``);``                ``}``                ``if` `(m.getKey() == s1 - m.getKey()) {``                    ``// Update the count of pairs` `                    ``c = c + m.getValue() / ``2``;` `                    ``// Divide the answer by the factorial``                    ``// of no. of similar pairs``                    ``ans = ans / factorial(m.getValue() / ``2``);` `                    ``// Make frequency of this element 0``                    ``mp.replace(m.getKey(),``0``);``                ``}``            ``}``        ``}``    ``}` `    ``// Check if it is possible to make the``    ``// array and there are n-1 pairs``    ``// whose sum will be equal to s1``    ``if` `(c < n - ``1` `&& isArrayPossible == ``false``) {``        ``System.out.println(``"0"``);``    ``}``    ``else` `{``        ``System.out.println(ans);``    ``}``}` `// Driver code``public` `static` `void` `main(String args[])``{``    ``int``[] arr1 = { ``5``, ``2``, ``3``, ``5` `};``    ``int` `n1 = arr1.length;` `    ``// Function calling``    ``findNoOfArrays(arr1, n1 / ``2``);` `    ``int` `[]arr2 = { -``1``, -``1``, -``1``, ``0``, ``1``, ``0``,``                ``1``, ``0``, ``1``, ``0``, ``0``, ``0` `};``    ``int` `n2 = arr2.length;``    ``findNoOfArrays(arr2, n2 / ``2``);``}``}` `// This code is contributed by Surendra_Gangwar`

## Python3

 `# Python3 implementation of the above approach` `# Function to find power of``# a number.``def` `power(a, b) :` `    ``result ``=` `1``;``    ``while` `(b > ``0``) :``        ``if` `(b ``%` `2` `=``=` `1``) :``            ``result ``=` `result ``*` `a;``        ``a ``=` `a ``*` `a;``        ``b ``=` `b ``/``/` `2``;``    ` `    ``return` `result;` `# Function to find``# factorial of a number.``def` `factorial(n) :` `    ``fact ``=` `1``;``    ``for` `i ``in` `range``(``1``, n ``+` `1``) :``        ``fact ``=` `fact ``*` `i;``    ` `    ``return` `fact;` `# Function to print no of arrays``def` `findNoOfArrays(a, n) :` `    ``# c variable counts the no of pairs``    ``sum` `=` `0``; c ``=` `0``;` `    ``# Map to store the frequency``    ``# of each element``    ``mp ``=` `dict``.fromkeys(a, ``0``);` `    ``for` `i ``in` `range``(``2` `*` `n) :``        ``mp[a[i]] ``+``=` `1``;` `        ``# Sum of all elements of the array``        ``sum` `=` `sum` `+` `a[i];` `    ``# Variable to check if it is``    ``# possible to make any array``    ``isArrayPossible ``=` `True``;``    ``ans ``=` `factorial(n ``-` `1``);` `    ``# First element of suffix array``    ``# and the last element of prefix array``    ``s1 ``=` `sum` `/``/` `(n ``+` `1``);` `    ``# Check if the element exists in the map``    ``if` `(mp[s1] >``=` `2``) :``        ``mp[s1] ``=` `mp[s1] ``-` `2``;``        ` `    ``else` `:``        ``isArrayPossible ``=` `False``;``    ` `    ``if` `(isArrayPossible) :``        ``for` `first,second ``in` `mp.items() :``            ` `            ``# If elements of any pair are equal``            ``# and their frequency is not divisible by 2``            ``# update the isArrayPossible variable``            ``# to false and break through the loop``            ``if` `(first ``=``=` `s1 ``-` `first) :``                ``if` `(mp[first] ``%` `2` `!``=` `0``) :``                    ``isArrayPossible ``=` `False``;``                    ``break``;` `            ``# If elements of any pair are not equal``            ``# and their frequency is not same``            ``# update the isArrayPossible variable``            ``# to false and break through the loop``            ``if` `(first !``=` `s1 ``-` `first) :``                ``if` `s1 ``-` `first ``in` `mp :``                    ``if` `(mp[first] !``=` `mp[s1 ``-` `first]) :``                        ``isArrayPossible ``=` `False``;``                        ``break``;``            ` `            ``# Check if frequency is greater than zero``            ``if` `(second > ``0``) :``                ``if` `(first !``=` `s1 ``-` `first) :` `                    ``# update the count of pairs``                    ``c ``=` `c ``+` `second;` `                    ``# Multiply the answer by``                    ``# 2^(frequency of pairs) since``                    ``# the elements of the pair are``                    ``# not the same in this condition``                    ``ans ``=` `ans ``*` `power(``2``, second);` `                    ``# Divide the answer by the factorial``                    ``# of no of similar pairs``                    ``ans ``=` `ans ``/` `factorial(second);` `                    ``# Make frequency of both these elements 0``                    ``mp[first] ``=` `0``;``                    ``mp[s1 ``-` `first] ``=` `0``;``                ` `                ``if` `(first ``=``=` `s1 ``-` `first) :` `                    ``# Update the count of pairs``                    ``c ``=` `c ``+` `second ``/``/` `2``;` `                    ``# Divide the answer by the factorial``                    ``# of no. of similar pairs``                    ``ans ``=` `ans ``/``/` `factorial(second ``/``/` `2``);` `                    ``# Make frequency of this element 0``                    ``mp[first] ``=` `0``;` `    ``# Check if it is possible to make the``    ``# array and there are n-1 pairs``    ``# whose sum will be equal to s1``    ``if` `(c < n ``-` `1` `or` `isArrayPossible ``=``=` `False``) :``        ``print``(``"0"``);``    ``else``:``        ``print``(ans);` `# Driver code``if` `__name__ ``=``=` `"__main__"` `:` `    ``arr1 ``=` `[ ``5``, ``2``, ``3``, ``5` `];``    ``n1 ``=` `len``(arr1);` `    ``# Function calling``    ``findNoOfArrays(arr1, n1 ``/``/` `2``);` `    ``arr2 ``=` `[ ``-``1``, ``-``1``, ``-``1``, ``0``, ``1``, ``0``,``                ``1``, ``0``, ``1``, ``0``, ``0``, ``0` `];``    ``n2 ``=` `len``(arr2);``    ``findNoOfArrays(arr2, n2 ``/``/` `2``);``    ` `# This code is contributed by AnkitRai01`

## Javascript

 `// JavaScript implementation of the above approach` `// Function to find power of``// a number.``function` `power(a, b)``{``    ``let result = 1;``    ``while` `(b > 0) {``        ``if` `(b % 2 == 1) {``            ``result = result * a;``        ``}``        ``a = a * a;``        ``b = Math.floor(b / 2);``    ``}``    ``return` `result;``}` `// Function to find``// factorial of a number.``function` `factorial(n)``{``    ``let fact = 1;``    ``for` `(let i = 1; i <= n; i++) {``        ``fact = fact * i;``    ``}``    ``return` `fact;``}` `// Function to print no of arrays``function` `findNoOfArrays(a, n)``{``    ``// c variable counts the no of pairs``    ``let sum = 0, s1, c = 0;` `    ``// Map to store the frequency``    ``// of each element``    ``let mp = {};``    ` `    ``let keys = []``    ``for` `(``var` `i = 0; i < 2 * n; i++)``    ``{``        ``var` `ele = a[i]``        ``if` `(!mp.hasOwnProperty(ele))``        ``{``            ``mp[ele] = 1``            ``keys.push(ele)``        ``}``        ``else``        ``{``            ``mp[ele] += 1``        ``}``        ` `            ` `    ` `        ``// Sum of all elements of the array``        ``sum += ele;``    ``}` `    ``// Variable to check if it is``    ``// possible to make any array``    ``let isArrayPossible = ``true``;``    ``let ans = factorial(n - 1);` `    ``// First element of suffix array``    ``// and the last element of prefix array``    ``s1 = Math.floor(sum / (n + 1));``    ` `    ``if` `(!mp.hasOwnProperty(s1))``        ``mp[s1] = 0;``        ` `    ``// Check if the element exists in the map``    ``if` `(mp[s1] >= 2) {``        ``mp[s1] = mp[s1] - 2;``    ``}``    ``else` `{``        ``isArrayPossible = ``false``;``    ``}``    `  `    ``if` `(isArrayPossible) {``        ``for` `(``var` `first of keys) {``            ``var` `second = mp[first]``            ` `            ``// If elements of any pair are equal``            ``// and their frequency is not divisible by 2``            ``// update the isArrayPossible variable``            ``// to false and break through the loop``            ``first = parseInt(first);``            ``second = parseInt(second);` `                ` `            ``if` `(first == s1 - first) {``                ``if` `(mp[first] % 2 != 0) {``                    ``isArrayPossible = ``false``;``                    ``break``;``                ``}``            ``}` `            ``// If elements of any pair are not equal``            ``// and their frequency is not same``            ``// update the isArrayPossible variable``            ``// to false and break through the loop``    ` `            ``if` `(first != s1 - first) {``                ``if` `(mp.hasOwnProperty(s1 - first))``                ``{``                    ``if` `(mp[first] != mp[s1 - first]) {``                        ``isArrayPossible = ``false``;``                        ``break``;``                    ``}``                ``}``            ``}``            ``// Check if frequency is greater than zero``            ``if` `(second > 0) {``                ``if` `(first != s1 - first) {``                    ``// update the count of pairs` `                    ``c = c + second;` `                    ``// Multiply the answer by``                    ``// 2^(frequency of pairs) since``                    ``// the elements of the pair are``                    ``// not the same in this condition` `                    ``ans = ans * power(2, second);` `                    ``// Divide the answer by the factorial``                    ``// of no of similar pairs` `                    ``ans = Math.floor(ans / factorial(second));` `                    ``// Make frequency of both these elements 0` `                    ``mp[first] = 0;``                    ``mp[s1 - first] = 0;``                ``}``                ``else` `{``                    ``// Update the count of pairs` `                    ``c = c + Math.floor(second / 2);` `                    ``// Divide the answer by the factorial``                    ``// of no. of similar pairs` `                    ``ans = Math.floor(ans / factorial(Math.floor(second / 2)));` `                    ``// Make frequency of this element 0``                    ``mp[first] = 0;``                ``}``                ` `            ``}``        ``}``    ``}` `    ``// Check if it is possible to make the``    ``// array and there are n-1 pairs``    ``// whose sum will be equal to s1``    ``if` `(c < n - 1 || isArrayPossible == ``false``) {``        ``console.log(0);``    ``}``    ``else` `{``        ``console.log(ans);``    ``}``    ` `}` `// Driver code``let arr1 = [ 5, 2, 3, 5 ];``let n1 = arr1.length;` `// Function calling``findNoOfArrays(arr1, Math.floor(n1 / 2));` `let arr2 =[ -1, -1, -1, 0, 1, 0,``                ``1, 0, 1, 0, 0, 0 ];``let n2 = arr2.length;``findNoOfArrays(arr2, Math.floor(n2 / 2));` `// This code is contributed by phasing17`

Output:

```2
80```

Time complexity: O(N Log(N))

Auxiliary Space: O(N)

My Personal Notes arrow_drop_up