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 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)
Last Updated :
18 Sep, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...