Open In App

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

Last Updated : 31 May, 2022
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)



Similar Reads

Check if a subarray of size K exists whose elements form a number divisible by 3
Given an array arr[], of size N and a positive integer K, the task is to find a subarray of size K whose elements can be used to generate a number which is divisible by 3. If no such subarray exists, then print -1. Examples: Input: arr[] = {84, 23, 45, 12 56, 82}, K = 3 Output: 12, 56, 82 Explanation: Number formed by the subarray {12, 56, 82} is 1
8 min read
First subarray having sum at least half the maximum sum of any subarray of size K
Given an array arr[] and an integer K, the task is to find the first subarray which has a sum greater than or equal to half of the maximum possible sum from any subarray of size K. Examples: Input: arr[] = {2, 4, 5, 1, 4, 6, 6, 2, 1, 0}, K = 3 Output: 6 2 1 Explanation: The given array has a maximum possible sum from any subarray of size K is 16 fr
9 min read
Subsequences of size three in an array whose sum is divisible by m
Given an array A[] (1&lt;=A[Tex]_i [/Tex]&lt;=10[Tex]^9 [/Tex]) of size N (1&lt;=N&lt;=10[Tex]^5 [/Tex]), find the number of subsequences of length 3 whose sum is divisible by M (1&lt;=M&lt;=10[Tex]^3 [/Tex]). Examples: Input : A[] = {1, 2, 4, 3} M = 3 Output : 2 Explanation : We can choose two such subsequence of length 3 such that its sum is divi
16 min read
Find a subarray of size K whose sum is a perfect square
Given an array arr[] and an integer K, the task is to find a subarray of length K having a sum which is a perfect square. If no such subarray exists, then print -1. Otherwise, print the subarray. Note: There can be more than one possible subarray. Print any one of them.Examples: Input: arr[] = {20, 34, 51, 10, 99, 87, 23, 45}, K = 3 Output: {10, 99
15 min read
Smallest subarray whose sum is multiple of array size
Given an array of size N, we need to find the smallest subarray whose sum is divisible by array size N. Examples : Input : arr[] = [1, 1, 2, 2, 4, 2] Output : [2 4] Size of array, N = 6 Following subarrays have sum as multiple of N [1, 1, 2, 2], [2, 4], [1, 1, 2, 2, 4, 2] The smallest among all is [2 4] We can solve this problem considering the bel
11 min read
Minimum cost to convert all elements of a K-size subarray to 0 from given Ternary Array with subarray sum as cost
Given an array arr[] of N integers, where each array element is either 0, 1, or 2, and an integer K, the task is to print the minimum cost needed to convert all the elements of the array to 0s by selecting a subarray of size K and converting any array element of the subarray to 0 in one operation with the cost equal to the sum of elements of the su
11 min read
Length of longest subarray whose sum is not divisible by integer K
Given an array arr[] of size N and an integer k, our task is to find the length of longest subarray whose sum of elements is not divisible by k. If no such subarray exists then return -1.Examples: Input: arr[] = {8, 4, 3, 1, 5, 9, 2}, k = 2 Output: 5 Explanation: The subarray is {8, 4, 3, 1, 5} with sum = 21, is not divisible by 2.Input: arr[] = {6
10 min read
Smallest subarray whose product leaves remainder K when divided by size of the array
Given an array arr[] of N integers and an integer K, the task is to find the length of the smallest subarray whose product when divided by N gives remainder K. If no such subarray exists the print "-1". Examples: Input: N = 3, arr = {2, 2, 6}, K = 1 Output: 2 Explanation: All possible subarrays are: {2} -&gt; 2(mod 3) = 2 {2} -&gt; 2(mod 3) = 2 {6}
6 min read
Maximum subarray size, such that all subarrays of that size have sum less than k
Given an array of n positive integers and a positive integer k, the task is to find the maximum subarray size such that all subarrays of that size have the sum of elements less than or equals to k. Examples : Input : arr[] = {1, 2, 3, 4} and k = 8. Output : 2 Sum of subarrays of size 1: 1, 2, 3, 4. Sum of subarrays of size 2: 3, 5, 7. Sum of subarr
16 min read
Find prime factors of Array elements whose sum of exponents is divisible by K
Given an array arr[] of N positive integers and an integer K., The task is to create a set of prime numbers such that the sum of all the powers of prime numbers in the prime factorization of all the array elements is divisible by K. Examples: Input: arr[] = {1, 2, 3}, K = 1 Output: {2, 3} Explanation: 2 = 21 3 = 31 The power of 2 is 1 which is divi
12 min read