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 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 which 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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of above approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to find a subarray
// whose sum is a multiple of N
void 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 code
int main()
{
    int arr[] = { 7, 5, 3, 7 };
  
    int N = sizeof(arr) / sizeof(arr[0]);
  
    CheckSubarray(arr, N);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of above approach
import java.io.*;
  
class GFG 
{
  
// Function to find a subarray
// whose sum is a multiple of N
static 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 code
public 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..

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of above approach
  
# Function to find a subarray
# whose sum is a multiple of N
def 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of above approach
using System;
  
class GFG 
{
  
// Function to find a subarray
// whose sum is a multiple of N
static 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 code
public static void Main ()
{
    int []arr = { 7, 5, 3, 7 };
  
    int N = arr.Length;
  
    CheckSubarray(arr, N);
  
}
}
  
// This code is contributed by anuj_67..

chevron_right


Output:

0 1

Time Complexity: O(N2)

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:

  1. If one of the above prefix sums is a multiple of N then print the ith subarray indices.
  2. 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 sub-array.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 N
void 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
    // startig 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 code
int main()
{
    int arr[] = { 7, 3, 5, 2 };
  
    int N = sizeof(arr) / sizeof(arr[0]);
  
    CheckSubarray(arr, N);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of above approach
import java.util.*;
  
class GFG
{
  
// Function to check is there exists a
// subarray whose sum is a multiple of N
static 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
    // startig 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 code
public static void main(String args[]) 
{
    int arr[] = {7, 3, 5, 2};
  
    int N = arr.length;
  
    CheckSubarray(arr, N);
}                     
}
  
// This code is contributed by 29AjayKumar

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python 3 implementation of above approach
  
# Function to check is there exists a
# subarray whose sum is a multiple of N
def 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
    # startig 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 code
if __name__ == '__main__':
    arr = [7, 3, 5, 2]
  
    N = len(arr)
  
    CheckSubarray(arr, N)
  
# This code is contributed by
# Surendra_Gangwar

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 N
static 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
    // startig 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 code
public 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

chevron_right


Output:

1 2

Time Complexity: O(N)



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

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.