Open In App

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

Improve
Improve
Like Article
Like
Save
Share
Report

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




// 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;
}


Java




// 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..


Python3




# 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


C#




// 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..


Javascript




<script>
// Javascript implementation of above approach
 
// Function to find a subarray
// whose sum is a multiple of N
function 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>


Output: 

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:

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


Java




// 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
    // 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 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


Python3




# 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
    # 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 code
if __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 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
    // 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 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


Javascript




<script>
 
// Javascript implementation of above approach
 
// Function to check is there exists a
// subarray whose sum is a multiple of N
function 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 code
let arr = [ 7, 3, 5, 2 ];
let N = arr.length;
  
CheckSubarray(arr, N);
 
// This code is contributed by unknown2108
 
</script>


Output: 

1 2

 

Time Complexity: O(n)

Auxiliary Space: O(n)



Last Updated : 31 May, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads