Count of possible arrays from prefix-sum and suffix-sum arrays
Last Updated :
27 Nov, 2023
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: 2
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 <bits/stdc++.h>
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[0]);
// 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[0]);
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<Integer,Integer> mp = new HashMap<Integer,Integer>();
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<Integer,Integer> 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
C#
using System;
using System.Collections.Generic;
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 *= a;
}
a *= a;
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 *= i;
}
return fact;
}
// Function to print the number of arrays
static void FindNoOfArrays(int[] a, int n)
{
int sum = 0, s1, c = 0;
Dictionary<int, int> mp
= new Dictionary<int, int>();
// Calculating the sum of elements and initializing
// the frequency in the dictionary
for (int i = 0; i < 2 * n; i++) {
if (!mp.ContainsKey(a[i])) {
mp[a[i]] = 1;
}
else {
mp[a[i]]++;
}
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.ContainsKey(s1) && mp[s1] >= 2) {
mp[s1] -= 2;
}
else {
isArrayPossible = false;
}
// Check if the array is possible based on frequency
// of elements
if (isArrayPossible) {
var keys = new List<int>(mp.Keys);
foreach(var key in keys)
{
if (mp.ContainsKey(s1 - key)) {
if (key == s1 - key) {
if (mp[key] % 2 != 0) {
isArrayPossible = false;
break;
}
}
else {
if (mp[key] != mp[s1 - key]) {
isArrayPossible = false;
break;
}
}
if (mp[key] > 0) {
if (key != s1 - key) {
c += mp[key];
ans *= Power(2, mp[key]);
ans /= Factorial(mp[key]);
mp[key] = 0;
mp[s1 - key] = 0;
}
if (key == s1 - key) {
c += mp[key] / 2;
ans /= Factorial(mp[key] / 2);
mp[key] = 0;
}
}
}
}
}
// Check if it is possible to make the array and if
// there are n-1 pairs whose sum will be equal to s1
if (c < n - 1 && !isArrayPossible) {
Console.WriteLine("0");
}
else {
Console.WriteLine(ans);
}
}
// Main method
public static void Main(string[] args)
{
// First input array and function call
int[] arr1 = { 5, 2, 3, 5 };
int n1 = arr1.Length;
FindNoOfArrays(arr1, n1 / 2);
// Second input array and function call
int[] arr2
= { -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0 };
int n2 = arr2.Length;
FindNoOfArrays(arr2, n2 / 2);
}
}
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
Time complexity: O(N Log(N))
Auxiliary Space: O(N)
Similar Reads
Find original Array from given Array where each element is sum of prefix and postfix sum Given an array arr[] of length N, where arr is derived from an array nums[] which is lost. Array arr[] is derived as: arr[i] = (nums[0] + nums[1] + ... + nums[i]) + (nums[i] + nums[i+1] + ... + nums[N-1]). The task is to find nums[] array of length N. Examples: Input: N = 4, arr[] = {9, 10, 11, 10}O
10 min read
Count of permutations of an Array having maximum MEXs sum of prefix arrays Given an array arr of size N, the task is to find the number of its permutations such that the sum of MEXs of its prefix arrays is maximum. Note: MEX of a set of integers is defined as the smallest non-negative integer that does not belong to this set. Example: Input: arr[] = {1, 0, 1}Output: 2Expla
10 min read
Count of indices up to which prefix and suffix sum is equal for given Array Given an array arr[] of integers, the task is to find the number of indices up to which prefix sum and suffix sum are equal. Example: Input: arr = [9, 0, 0, -1, 11, -1]Output: 2Explanation: The indices up to which prefix and suffix sum are equal are given below:At index 1 prefix and suffix sum are 9
15+ min read
Count pairs of indices having equal prefix and suffix sums Given an array arr[] of length N, the task is to find the count of pairs of indices (i, j) (0-based indexing) such that prefix sum of the subarray {arr[0], ... arr[i]} is equal to the suffix sum of the subarray {arr[N - 1], ..., arr[j]} ( 0 ? i, j < N). Examples: Input: arr[] = {1, 2, 1, 1}Output
6 min read
Sum of decomposition values of all suffixes of an Array Given an array arr[], the task is to find the sum of the decomposition value of the suffixes subarray.Decomposition Value: The decomposition value of a subarray is the count of the partition in the subarray possible. The partition in the array at index i can be done only if the elements of the array
8 min read
Minimum common sum from K arrays after removing some part of their suffix Given K (K > 2) arrays of different sizes in a 2D list arr[][] where elements in each array are non-negative. Find the minimum common sum of K arrays after removing part of the suffix(possibly none) from each array. Examples: Input: K = 3, arr = {{5, 2, 4}, {1, 4, 1, 1}, {2, 3}}Output: 5Explanati
7 min read
Count pair of indices in Array having equal Prefix-MEX and Suffix-MEX Given an array arr[] of N elements, the task is to find the number of pairs of indices such that the Prefix-MEX of the one index is equal to the Suffix-MEX of the other index. Order of indices in pair matters. MEX of an array refers to the smallest missing non-negative integer of the array. For the
10 min read
Count of distinct substrings of a string using Suffix Array Given a string of length n of lowercase alphabet characters, we need to count total number of distinct substrings of this string. Examples: Input : str = âababaâ Output : 10 Total number of distinct substring are 10, which are, "", "a", "b", "ab", "ba", "aba", "bab", "abab", "baba" and "ababa"Reco
15+ min read
Original Array from given Prefix Sums You are given a prefix sum array presum[] of an array arr[]. The task is to find the original array arr[] whose prefix sum is presum[].Examples: Input: presum[] = {5, 7, 10, 11, 18}Output: [5, 2, 3, 1, 7]Explanation: Original array {5, 2, 3, 1, 7} Prefix sum array = {5, 5+2, 5+2+3, 5+2+3+1, 5+2+3+1+
4 min read
Count permutations whose prefix & suffix AND are same for each index Given an array arr[] of size N, Return the number of permutations of array arr[] which satisfy the condition arr[1] & arr[2] & . . . & arr[i] = arr[i+1] & arr[i+2] & . . . & arr[N] , for all i. Note: Here & denotes the bitwise AND operation. Examples: Input: N = 3, arr[]
7 min read