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++
// 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.. |
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:
- 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 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 // 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; } |
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 // 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 |
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 # 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 |
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 // 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 |
1 2
Time Complexity: O(N)
Recommended Posts:
- Count number of permutation of an Array having no SubArray of size two or more from original Array
- Smallest subarray whose sum is multiple of array size
- Find maximum (or minimum) sum of a subarray of size k
- Subsequences of size three in an array whose sum is divisible by m
- Maximum subarray size, such that all subarrays of that size have sum less than k
- Find array such that no subarray has xor zero or Y
- Find mean of subarray means in a given array
- Find the longest Fibonacci-like subarray of the given array
- Find if there is any subset of size K with 0 sum in an array of -1 and +1
- Find Maximum XOR value of a sub-array of size k
- Find an array element such that all elements are divisible by it
- Subarray of size k with given sum
- Find the only repeating element in a sorted array of size n
- Given an array of size n and a number k, find all elements that appear more than n/k times
- Size of The Subarray With Maximum Sum
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.