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 codearr = [ 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!



