Find a subarray whose sum is divisible by size of the array (original) (raw)
Last Updated : 31 May, 2022
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 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
`
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 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
`
Time Complexity: O(n)
Auxiliary Space: O(n)