Smallest subarray whose sum is multiple of array size
Last Updated :
18 Sep, 2023
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 below facts,
Let S[i] denotes sum of first i elements i.e.
S[i] = a[1] + a[2] .. + a[i]
Now subarray arr(i, i + x) has sum multiple of N then,
(arr(i] + arr[i+1] + .... + arr[i + x])) % N = 0
(S[i+x] – S[i] ) % N = 0
S[i] % N = S[i + x] % N
We need to find the minimum value of x for which the above condition holds. This can be implemented in a single iteration with O(N) time-complexity using another array modIdx of size N. Array modIdx is initialized with all elements as -1. modIdx[k] is to be updated with i in each iteration, where k = sum % N.
Now in each iteration, we need to update modIdx[k] according to the value of sum % N.
We need to check two things,
If at any instant k = 0 and it is the first time we are updating modIdx[0] (i.e. modIdx[0] was -1)
Then we assign x to i + 1, because (i + 1) will be the length of subarray whose sum is multiple of N
In another case whenever we get a mod value, if this index is not -1, that means it is updated by some other sum value, whose index is stored at that index, we update x with this difference value, i.e. by i – modIdx[k].
After each above operation, we update the minimum value of length and corresponding starting index and end index for the subarray. Finally, this gives the solution to our problem.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
void printSubarrayMultipleOfN( int arr[], int N)
{
int modIdx[N];
for ( int i = 0; i < N; i++)
modIdx[i] = -1;
int minLen = N + 1;
int curLen = N + 1;
int sum = 0;
int l, r;
for ( int i = 0; i < N; i++)
{
sum += arr[i];
sum %= N;
if (modIdx[sum] == -1 && sum == 0)
curLen = i + 1;
if (modIdx[sum] != -1)
curLen = i - modIdx[sum];
if (curLen < minLen)
{
minLen = curLen;
l = modIdx[sum] + 1;
r = i;
}
modIdx[sum] = i;
}
for ( int i = l; i <= r; i++)
cout << arr[i] << " " ;
cout << endl;
}
int main()
{
int arr[] = {1, 1, 2, 2, 4, 2};
int N = sizeof (arr) / sizeof ( int );
printSubarrayMultipleOfN(arr, N);
return 0;
}
|
Java
class GFG {
static void printSubarrayMultipleOfN( int arr[],
int N)
{
int modIdx[] = new int [N];
for ( int i = 0 ; i < N; i++)
modIdx[i] = - 1 ;
int minLen = N + 1 ;
int curLen = N + 1 ;
int sum = 0 ;
int l = 0 , r = 0 ;
for ( int i = 0 ; i < N; i++) {
sum += arr[i];
sum %= N;
if (modIdx[sum] == - 1 && sum == 0 )
curLen = i + 1 ;
if (modIdx[sum] != - 1 )
curLen = i - modIdx[sum];
if (curLen < minLen) {
minLen = curLen;
l = modIdx[sum] + 1 ;
r = i;
}
modIdx[sum] = i;
}
for ( int i = l; i <= r; i++)
System.out.print(arr[i] + " " );
System.out.println();
}
public static void main(String arg[])
{
int arr[] = { 1 , 1 , 2 , 2 , 4 , 2 };
int N = arr.length;
printSubarrayMultipleOfN(arr, N);
}
}
|
Python3
def printSubarrayMultipleOfN(arr, N):
modIdx = [ 0 for i in range (N)]
for i in range (N):
modIdx[i] = - 1
minLen = N + 1
curLen = N + 1
sum = 0
l = 0 ; r = 0
for i in range (N):
sum + = arr[i]
sum % = N
if (modIdx[ sum ] = = - 1 and sum = = 0 ):
curLen = i + 1
if (modIdx[ sum ] ! = - 1 ):
curLen = i - modIdx[ sum ]
if (curLen < minLen):
minLen = curLen
l = modIdx[ sum ] + 1
r = i
modIdx[ sum ] = i
for i in range (l, r + 1 ):
print (arr[i] , " " , end = "")
print ()
arr = [ 1 , 1 , 2 , 2 , 4 , 2 ]
N = len (arr)
printSubarrayMultipleOfN(arr, N)
|
C#
using System;
class GFG {
static void printSubarrayMultipleOfN( int []arr,
int N)
{
int []modIdx = new int [N];
for ( int i = 0; i < N; i++)
modIdx[i] = -1;
int minLen = N + 1;
int curLen = N + 1;
int sum = 0;
int l = 0, r = 0;
for ( int i = 0; i < N; i++) {
sum += arr[i];
sum %= N;
if (modIdx[sum] == -1 && sum == 0)
curLen = i + 1;
if (modIdx[sum] != -1)
curLen = i - modIdx[sum];
if (curLen < minLen) {
minLen = curLen;
l = modIdx[sum] + 1;
r = i;
}
modIdx[sum] = i;
}
for ( int i = l; i <= r; i++)
Console.Write(arr[i] + " " );
Console.WriteLine();
}
public static void Main()
{
int []arr = {1, 1, 2, 2, 4, 2};
int N = arr.Length;
printSubarrayMultipleOfN(arr, N);
}
}
|
PHP
<?php
function printSubarrayMultipleOfN( $arr ,
$N )
{
$modIdx = array ();
for ( $i = 0; $i < $N ; $i ++)
$modIdx [ $i ] = -1;
$minLen = $N + 1;
$curLen = $N + 1;
$sum = 0;
$l ; $r ;
for ( $i = 0; $i < $N ; $i ++)
{
$sum += $arr [ $i ];
$sum %= $N ;
if ( $modIdx [ $sum ] == -1 &&
$sum == 0)
$curLen = $i + 1;
if ( $modIdx [ $sum ] != -1)
$curLen = $i - $modIdx [ $sum ];
if ( $curLen < $minLen )
{
$minLen = $curLen ;
$l = $modIdx [ $sum ] + 1;
$r = $i ;
}
$modIdx [ $sum ] = $i ;
}
for ( $i = $l ; $i <= $r ; $i ++)
echo $arr [ $i ] , " " ;
echo "\n" ;
}
$arr = array (1, 1, 2, 2, 4, 2);
$N = count ( $arr );
printSubarrayMultipleOfN( $arr , $N );
?>
|
Javascript
<script>
function printSubarrayMultipleOfN(arr, N)
{
let modIdx = new Array(N);
for (let i = 0; i < N; i++)
modIdx[i] = -1;
let minLen = N + 1;
let curLen = N + 1;
let sum = 0;
let l = 0, r = 0;
for (let i = 0; i < N; i++) {
sum += arr[i];
sum %= N;
if (modIdx[sum] == -1 && sum == 0)
curLen = i + 1;
if (modIdx[sum] != -1)
curLen = i - modIdx[sum];
if (curLen < minLen) {
minLen = curLen;
l = modIdx[sum] + 1;
r = i;
}
modIdx[sum] = i;
}
for (let i = l; i <= r; i++)
document.write(arr[i] + " " );
document.write( "</br>" );
}
let arr = [1, 1, 2, 2, 4, 2];
let N = arr.length;
printSubarrayMultipleOfN(arr, N);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...