Find a subarray whose sum is divisible by size of the array

31 May, 2022
Given an array arr[] of length N. The task is to check if there exists any subarray whose sum is a multiple of N. If there exists such subarray, then print the starting and ending index of that subarray else print -1. If there are multiple such subarrays, print any of them.
Examples: 
Input: arr[] = {7, 5, 3, 7} Output: 0 1 Sub-array from index 0 to 1 is [7, 5] sum of this subarray is 12 which is a multiple of 4
Input: arr[] = {3, 7, 14} Output: 0 0 
Naive Approach: The naive approach is to generate all the sub-arrays and calculate their sum. If the sum for any subarray is a multiple of N, then return the starting as well as ending index.
Time Complexity: O(N3)
Better Approach: A better approach is to maintain a prefix sum array that stores the sum of all previous elements. To calculate the sum of a subarray between index i and j, we can use the formula: 
subarray sum[i:j] = presum[j]-presum[i-1] 
Now check for every sub-array whether its sum is a multiple of N or not.
Below is the implementation of the above approach: 
C++
Java
Python3
C#
Javascript
// C++ implementation of above approach#include <bits/stdc++.h>using namespace std; // Function to find a subarray// whose sum is a multiple of Nvoid CheckSubarray(int arr[], int N){     // Prefix sum array to store cumulative sum    int presum[N + 1] = { 0 };     // Single state dynamic programming    // relation for prefix sum array    for (int i = 1; i <= N; i += 1) {         presum[i] = presum[i - 1] + arr[i - 1];    }     // Generating all sub-arrays    for (int i = 1; i <= N; i += 1) {         for (int j = i; j <= N; j += 1) {             // If the sum of the sub-array[i:j]            // is a multiple of N            if ((presum[j] - presum[i - 1]) % N == 0) {                cout << i - 1 << " " << j - 1;                return;            }        }    }     // If the function reaches here it means    // there are no subarrays with sum    // as a multiple of N    cout << -1;} // Driver codeint main(){    int arr[] = { 7, 5, 3, 7 };     int N = sizeof(arr) / sizeof(arr[0]);     CheckSubarray(arr, N);     return 0;}
// Java implementation of above approachimport java.io.*; class GFG{ // Function to find a subarray// whose sum is a multiple of Nstatic void CheckSubarray(int arr[], int N){     // Prefix sum array to store cumulative sum    int presum[] = new int[N + 1];     // Single state dynamic programming    // relation for prefix sum array    for (int i = 1; i <= N; i += 1)    {         presum[i] = presum[i - 1] + arr[i - 1];    }     // Generating all sub-arrays    for (int i = 1; i <= N; i += 1)    {         for (int j = i; j <= N; j += 1)        {             // If the sum of the sub-array[i:j]            // is a multiple of N            if ((presum[j] - presum[i - 1]) % N == 0)            {                System.out.print((i - 1) + " " + (j - 1));                return;            }        }    }     // If the function reaches here it means    // there are no subarrays with sum    // as a multiple of N    System.out.print(-1);} // Driver codepublic static void main (String[] args){    int []arr = { 7, 5, 3, 7 };     int N = arr.length;     CheckSubarray(arr, N); }} // This code is contributed by anuj_67..
# Python3 implementation of above approach # Function to find a subarray# whose sum is a multiple of Ndef CheckSubarray(arr, N):     # Prefix sum array to store cumulative sum    presum=[0 for i in range(N + 1)]     # Single state dynamic programming    # relation for prefix sum array    for i in range(1, N+1):        presum[i] = presum[i - 1] + arr[i - 1]     # Generating all sub-arrays    for i in range(1, N+1):         for j in range(i, N+1):             # If the sum of the sub-array[i:j]            # is a multiple of N            if ((presum[j] - presum[i - 1]) % N == 0):                print(i - 1,j - 1)                return      # If the function reaches here it means    # there are no subarrays with sum    # as a multiple of N    print("-1") # Driver code arr = [ 7, 5, 3, 7] N = len(arr) CheckSubarray(arr, N) # This code is contributed by mohit kumar 29
// C# implementation of above approachusing System; class GFG{ // Function to find a subarray// whose sum is a multiple of Nstatic void CheckSubarray(int []arr, int N){     // Prefix sum array to store cumulative sum    int []presum = new int[N + 1];     // Single state dynamic programming    // relation for prefix sum array    for (int i = 1; i <= N; i += 1)    {         presum[i] = presum[i - 1] + arr[i - 1];    }     // Generating all sub-arrays    for (int i = 1; i <= N; i += 1)    {         for (int j = i; j <= N; j += 1)        {             // If the sum of the sub-array[i:j]            // is a multiple of N            if ((presum[j] - presum[i - 1]) % N == 0)            {                Console.Write((i - 1) + " " + (j - 1));                return;            }        }    }     // If the function reaches here it means    // there are no subarrays with sum    // as a multiple of N    Console.Write(-1);} // Driver codepublic static void Main (){    int []arr = { 7, 5, 3, 7 };     int N = arr.Length;     CheckSubarray(arr, N); }} // This code is contributed by anuj_67..
<script>// Javascript implementation of above approach // Function to find a subarray// whose sum is a multiple of Nfunction CheckSubarray(arr, N){     // Prefix sum array to store cumulative sum    let presum = new Array(N + 1).fill(0);     // Single state dynamic programming    // relation for prefix sum array    for (let i = 1; i <= N; i += 1) {         presum[i] = presum[i - 1] + arr[i - 1];    }     // Generating all sub-arrays    for (let i = 1; i <= N; i += 1) {         for (let j = i; j <= N; j += 1) {             // If the sum of the sub-array[i:j]            // is a multiple of N            if ((presum[j] - presum[i - 1]) % N == 0) {                document.write((i - 1) + " " + (j - 1));                return;            }        }    }     // If the function reaches here it means    // there are no subarrays with sum    // as a multiple of N    document.write(-1);} // Driver code    let arr = [ 7, 5, 3, 7 ];     let N = arr.length;     CheckSubarray(arr, N); </script>
0 1
 
Time Complexity: O(N2)
Auxiliary Space: O(N)
Efficient Approach: The idea is to use the Pigeon-Hole Principle. Let’s suppose the array elements are a1, a2...aN. For a sequence of numbers as follows:  
a1, a1 + a2, a1 + a2 + a3, ..., a1 + a2 +a3 + ... +aN  
In the above sequence, there are N terms. There are two possible cases:
If one of the above prefix sums is a multiple of N then print the ith subarray indices.If None of the above sequence elements lies in the 0 modulo class of N, then there are (N – 1) modulo classes left. By the pigeon-hole principle, there are N pigeons (elements of the prefix sum sequence) and (N – 1) holes (modulo classes), we can say that at least two elements would lie in the same modulo class. The difference between these two elements would give a sub-array whose sum will be a multiple of N.
If one of the above prefix sums is a multiple of N then print the ith subarray indices.
If None of the above sequence elements lies in the 0 modulo class of N, then there are (N – 1) modulo classes left. By the pigeon-hole principle, there are N pigeons (elements of the prefix sum sequence) and (N – 1) holes (modulo classes), we can say that at least two elements would lie in the same modulo class. The difference between these two elements would give a sub-array whose sum will be a multiple of N.
It could be seen that it is always possible to get such a sub-array.
Below is the implementation of the above approach:  
C++
Java
Python3
C#
Javascript
// C++ implementation of above approach#include <bits/stdc++.h>using namespace std; // Function to check is there exists a// subarray whose sum is a multiple of Nvoid CheckSubarray(int arr[], int N){     // Prefix sum array to store cumulative sum    int presum[N + 1] = { 0 };     // Single state dynamic programming    // relation for prefix sum array    for (int i = 1; i <= N; i += 1) {         presum[i] = presum[i - 1] + arr[i - 1];    }     // Modulo class vector    vector<int> moduloclass[N];     // Storing the index value in the modulo class vector    for (int i = 1; i <= N; i += 1) {        moduloclass[presum[i] % N].push_back(i - 1);    }     // If there exists a sub-array with    // starting index equal to zero    if (moduloclass[0].size() > 0) {        cout << 0 << " " << moduloclass[0][0];        return;    }     for (int i = 1; i < N; i += 1) {         // In this class, there are more than two presums%N        // Hence difference of any two subarrays would be a        // multiple of N        if (moduloclass[i].size() >= 2) {             // 0 based indexing            cout << moduloclass[i][0] + 1 << " " << moduloclass[i][1];            return;        }    }} // Driver codeint main(){    int arr[] = { 7, 3, 5, 2 };     int N = sizeof(arr) / sizeof(arr[0]);     CheckSubarray(arr, N);     return 0;}
// Java implementation of above approachimport java.util.*; class GFG{ // Function to check is there exists a// subarray whose sum is a multiple of Nstatic void CheckSubarray(int arr[], int N){     // Prefix sum array to store cumulative sum    int[] presum = new int[N + 1];     // Single state dynamic programming    // relation for prefix sum array    for (int i = 1; i <= N; i += 1)    {        presum[i] = presum[i - 1] + arr[i - 1];    }     // Modulo class vector    Vector<Integer>[] moduloclass = new Vector[N];    for (int i = 0; i < N; i += 1)    {        moduloclass[i] = new Vector<>();    }     // Storing the index value    // in the modulo class vector    for (int i = 1; i <= N; i += 1)    {        moduloclass[presum[i] % N].add(i - 1);    }     // If there exists a sub-array with    // starting index equal to zero    if (moduloclass[0].size() > 0)    {        System.out.print(0 + " " +               moduloclass[0].get(0));        return;    }     for (int i = 1; i < N; i += 1)    {         // In this class, there are more than        // two presums%N. Hence difference of        // any two subarrays would be a multiple of N        if (moduloclass[i].size() >= 2)        {             // 0 based indexing            System.out.print(moduloclass[i].get(0) + 1 +                       " " + moduloclass[i].get(1));            return;        }    }} // Driver codepublic static void main(String args[]){    int arr[] = {7, 3, 5, 2};     int N = arr.length;     CheckSubarray(arr, N);}                    } // This code is contributed by 29AjayKumar
# Python 3 implementation of above approach # Function to check is there exists a# subarray whose sum is a multiple of Ndef CheckSubarray(arr, N):    # Prefix sum array to store cumulative sum    presum = [0 for i in range(N+1)]     # Single state dynamic programming    # relation for prefix sum array    for i in range(1,N+1):        presum[i] = presum[i - 1] + arr[i - 1]     # Modulo class vector    moduloclass = [[]]*N     # Storing the index value in the modulo class vector    for i in range(1,N+1,1):        moduloclass[presum[i] % N].append(i - 1)     # If there exists a sub-array with    # starting index equal to zero    if (len(moduloclass[0]) > 0):        print(0+1,moduloclass[0][0]+2)        return     for i in range(1,N):        # In this class, there are more than two presums%N        # Hence difference of any two subarrays would be a        # multiple of N        if (len(moduloclass[i]) >= 2):            # 0 based indexing            print(moduloclass[i][0] + 1,moduloclass[i][1])            return# Driver codeif __name__ == '__main__':    arr = [7, 3, 5, 2]     N = len(arr)     CheckSubarray(arr, N) # This code is contributed by# Surendra_Gangwar
// C# implementation of the approachusing System;using System.Collections.Generic; class GFG{ // Function to check is there exists a// subarray whose sum is a multiple of Nstatic void CheckSubarray(int []arr, int N){     // Prefix sum array to store cumulative sum    int[] presum = new int[N + 1];     // Single state dynamic programming    // relation for prefix sum array    for (int i = 1; i <= N; i += 1)    {        presum[i] = presum[i - 1] + arr[i - 1];    }     // Modulo class vector    List<int>[] moduloclass = new List<int>[N];    for (int i = 0; i < N; i += 1)    {        moduloclass[i] = new List<int>();    }     // Storing the index value    // in the modulo class vector    for (int i = 1; i <= N; i += 1)    {        moduloclass[presum[i] % N].Add(i - 1);    }     // If there exists a sub-array with    // starting index equal to zero    if (moduloclass[0].Count > 0)    {        Console.Write(0 + " " +            moduloclass[0][0]);        return;    }     for (int i = 1; i < N; i += 1)    {         // In this class, there are more than        // two presums%N. Hence difference of        // any two subarrays would be a multiple of N        if (moduloclass[i].Count >= 2)        {             // 0 based indexing            Console.Write(moduloclass[i][0] + 1 +                    " " + moduloclass[i][1]);            return;        }    }} // Driver codepublic static void Main(String []args){    int []arr = {7, 3, 5, 2};     int N = arr.Length;     CheckSubarray(arr, N);}                    } // This code is contributed by Rajput-Ji
<script> // Javascript implementation of above approach // Function to check is there exists a// subarray whose sum is a multiple of Nfunction CheckSubarray(arr, N){         // Prefix sum array to store cumulative sum    let presum = new Array(N + 1);     for(let i = 0; i < (N + 1); i++)        presum[i] = 0;             // Single state dynamic programming    // relation for prefix sum array    for(let i = 1; i <= N; i += 1)    {        presum[i] = presum[i - 1] + arr[i - 1];    }      // Modulo class vector    let moduloclass = new Array(N);    for(let i = 0; i < N; i += 1)    {        moduloclass[i] = [];    }      // Storing the index value    // in the modulo class vector    for(let i = 1; i <= N; i += 1)    {        moduloclass[presum[i] % N].push(i - 1);    }      // If there exists a sub-array with    // starting index equal to zero    if (moduloclass[0].length > 0)    {        document.write(0 + " " +                       moduloclass[0][0]);        return;    }      for(let i = 1; i < N; i += 1)    {                 // In this class, there are more than        // two presums%N. Hence difference of        // any two subarrays would be a multiple of N        if (moduloclass[i].length >= 2)        {                         // 0 based indexing            document.write(moduloclass[i][0] + 1 +                     " " + moduloclass[i][1]);            return;        }    }} // Driver codelet arr = [ 7, 3, 5, 2 ];let N = arr.length;  CheckSubarray(arr, N); // This code is contributed by unknown2108 </script>
1 2
 
Time Complexity: O(n)
Auxiliary Space: O(n)
mohit kumar 29
vt_m
SURENDRA_GANGWAR
29AjayKumar
Rajput-Ji
subham348
arorakashish0911
unknown2108
rishavnitro
prefix-sum
subarray
subarray-sum
Arrays
Mathematical
prefix-sum
Arrays
Mathematical
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Introduction to Data Structures
Window Sliding Technique
Search, insert and delete in an unsorted array
Chocolate Distribution Problem
Find duplicates in O(n) time and O(1) extra space | Set 1
Program for Fibonacci numbers
Set in C++ Standard Template Library (STL)
Write a program to print all permutations of a given string
C++ Data Types
Coin Change | DP-7