Find the sums for which an array can be divided into sub-arrays of equal sum

Given an array of integers arr[], the task is to find all the values for sum such that for a value sum[i] the array can be divided into sub-arrays of sum equal to sum[i]. If array cannot be divided into sub-arrays of equal sum then print -1.

Examples:

Input: arr[] = {2, 2, 2, 1, 1, 2, 2}
Output: 2 4 6
The array can be divided into sub-arrays of sum 2, 4 and 6.
{2}, {2}, {2}, {1, 1}, {2} and {2}
{2, 2}, {2, 1, 1} and {2, 2}
{2, 2, 2} and {1, 1, 2, 2}

Input: arr[] = {1, 1, 2}
Output: 2
The array can be divided into sub-arrays of sum 2.
{1, 1} and {2}



Approach: Make a Prefix Sum Array P[] where P[i] stores the sum of elements from index 0 to i. The divisors of the total sum S can only be the possible sub-array sum. So for every divisor, if all the multiples of the divisor upto total sum S are present in the array P[], then that would be a possible sub-array sum. Mark all the elements of P[] into a Map as 1 so that look-up would be easy. All the divisors can be checked in sqrt(S) time.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find the sums for which an array
// can be divided into subarrays of equal sum.
#include <bits/stdc++.h>
using namespace std;
  
// Function to find the sums for which an array
// can be divided into subarrays of equal sum
void getSum(int a[], int n)
{
    int P[n];
  
    // Creating prefix sum array
    P[0] = a[0];
    for (int i = 1; i < n; i++)
        P[i] = a[i] + P[i - 1];
  
    // Total Sum
    int S = P[n - 1];
  
    // Initializing a Map for look-up
    map<int, int> hash;
  
    // Setting all the present sum as 1
    for (int i = 0; i < n; i++)
        hash[P[i]] = 1;
  
    // Set to store the subarray sum
    set<int> res;
  
    // Check the divisors of S
    for (int i = 1; i * i <= S; i++) {
        if (S % i == 0) {
            bool pres = true;
  
            int div1 = i, div2 = S / i;
  
            // Check if all multiples of div1 present or not
            for (int j = div1; j <= S; j += div1) {
                if (hash[j] != 1) {
                    pres = false;
                    break;
                }
            }
  
            // If all multiples are present
            if (pres and div1 != S)
                res.insert(div1);
  
            pres = true;
  
            // Check if all multiples of div2 present or not
            for (int j = S / i; j <= S; j += S / i) {
                if (hash[j] != 1) {
                    pres = false;
                    break;
                }
            }
  
            // If all multiples are present
            if (pres and div2 != S)
                res.insert(div2);
        }
    }
  
    // If array cannot be divided into 
    // sub-arrays of equal sum
    if(res.size() == 0) {
        cout << "-1";
        return;
    }
  
    // Printing the results
    for (auto i : res)
        cout << i << " ";
}
  
// Driver code
int main()
{
    int a[] = { 1, 2, 1, 1, 1, 2, 1, 3 };
  
    int n = sizeof(a) / sizeof(a[0]);
  
    getSum(a, n);
  
    return 0;
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to find the sums for 
# which an array can be divided into 
# subarrays of equal sum. 
  
# from math lib import sqrt function
from math import sqrt
  
# Function to find the sums for which 
# an array can be divided into subarrays 
# of equal sum 
def getSum(a, n) :
      
    P = [0] *
  
    # Creating prefix sum array 
    P[0] = a[0]
    for i in range(1, n) : 
        P[i] = a[i] + P[i - 1]
  
    # Total Sum 
    S = P[n - 1
  
    # Initializing a Map for look-up 
    hash = {}
  
    # Setting all the present sum as 1 
    for i in range(n) :
        hash[P[i]] = 1
  
    # Set to store the subarray sum 
    res = set()
  
    # Check the divisors of S 
    for i in range(1, int(sqrt(S)) + 1) : 
        if (S % i == 0) :
            pres = True
  
            div1 = i
            div2 = S // i
  
            # Check if all multiples of 
            # div1 present or not 
            for j in range(div1 , S + 1, div1) :
                  
                if j not in hash.keys() :
                    pres = False
                    break
  
            # If all multiples are present 
            if (pres and div1 != S) :
                res.add(div1)
  
            pres = True
  
            # Check if all multiples of div2 
            # present or not 
            for j in range(S // i , S + 1 , S // i) : 
                if j not in hash.keys():
                    pres = False
                    break
  
            # If all multiples are present 
            if (pres and div2 != S) :
                res.add(div2)
  
    # If array cannot be divided into 
    # sub-arrays of equal sum 
    if(len(res) == 0) :
        print("-1"
        return
  
    # Printing the results 
    for i in res :
        print(i, end = " ")
  
# Driver code 
if __name__ == "__main__" :
  
    a = [ 1, 2, 1, 1, 1, 2, 1, 3 ]
  
    n = len(a)
  
    getSum(a, n)
  
# This code is contributed by Ryuga

chevron_right


Output:

3 4 6


My Personal Notes arrow_drop_up

Coder Machine Learner Social Activist Vocalist

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : AnkitRai01