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

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 4Input: 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++
// 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
// 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
# 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#
// 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.. |
Javascript
<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.
It could be seen that it is always possible to get such a sub-array.
Below is the implementation of the above approach:Â Â
C++
// 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
// 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 |
Python3
# 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#
// C# implementation of the approach using 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 |
Javascript
<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)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



