Smallest subarray whose sum is multiple of array size

Given an array of size N, we need to find smallest sized 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 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 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 other 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.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find subarray whose sum
// is multiple of size
#include <bits/stdc++.h>
using namespace std;
  
// Method prints smallest subarray whose sum is
// multiple of size
void printSubarrayMultipleOfN(int arr[], int N)
{
    // A direct index table to see if sum % N
    // has appeared before or not.   
    int modIdx[N]; 
  
    //  initialize all mod index with -1
    for (int i = 0; i < N; i++)
        modIdx[i] = -1;
  
    // initializing minLen and curLen with larger
    // values
    int minLen = N + 1;
    int curLen = N + 1;
  
    // To store sum of array elements
    int sum = 0;
  
    //  looping for each value of array
    int l, r;
    for (int i = 0; i < N; i++)
    {
        sum += arr[i];
        sum %= N;
  
        // If this is the first time we have
        // got mod value as 0, then S(0, i) % N
        // == 0
        if (modIdx[sum] == -1 && sum == 0)
            curLen = i + 1;
  
        // If we have reached this mod before then
        // length of subarray will be i - previous_position
        if (modIdx[sum] != -1)
            curLen = i - modIdx[sum];
  
        //  choose minimum length os subarray till now
        if (curLen < minLen)
        {
            minLen = curLen;
  
            //  update left and right indices of subarray
            l = modIdx[sum] + 1;
            r = i;
        }
        modIdx[sum] = i;
    }
  
    //  print subarray
    for (int i = l; i <= r; i++)
        cout << arr[i] << " ";
    cout << endl;
}
  
//  Driver code to test above method
int main()
{
    int arr[] = {1, 1, 2, 2, 4, 2};
    int N = sizeof(arr) / sizeof(int);
  
    printSubarrayMultipleOfN(arr, N);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find subarray whose sum
// is multiple of size
class GFG {
      
    // Method prints smallest subarray whose sum is
    // multiple of size
    static void printSubarrayMultipleOfN(int arr[], 
                                              int N)
    {
          
        // A direct index table to see if sum % N
        // has appeared before or not.
        int modIdx[] = new int[N];
  
        // initialize all mod index with -1
        for (int i = 0; i < N; i++)
            modIdx[i] = -1;
  
        // initializing minLen and curLen with 
        // larger values
        int minLen = N + 1;
        int curLen = N + 1;
  
        // To store sum of array elements
        int sum = 0;
  
        // looping for each value of array
        int l = 0, r = 0;
          
        for (int i = 0; i < N; i++) {
            sum += arr[i];
            sum %= N;
  
            // If this is the first time we 
            // have got mod value as 0, then 
            // S(0, i) % N == 0
            if (modIdx[sum] == -1 && sum == 0)
                curLen = i + 1;
  
            // If we have reached this mod before 
            // then length of subarray will be i 
            // - previous_position
            if (modIdx[sum] != -1)
                curLen = i - modIdx[sum];
  
            // choose minimum length os subarray 
            // till now
            if (curLen < minLen) {
                minLen = curLen;
  
                // update left and right indices 
                // of subarray
                l = modIdx[sum] + 1;
                r = i;
            }
              
            modIdx[sum] = i;
        }
  
        // print subarray
        for (int i = l; i <= r; i++)
            System.out.print(arr[i] + " ");
              
        System.out.println();
    }
      
    // Driver program
    public static void main(String arg[])
    {
        int arr[] = { 1, 1, 2, 2, 4, 2 };
        int N = arr.length;
  
        printSubarrayMultipleOfN(arr, N);
    }
}
  
// This code is contributed by Anant Agarwal.

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to find subarray 
# whose sum is multiple of size
  
# Method prints smallest subarray 
# whose sum is multiple of size
def printSubarrayMultipleOfN(arr, N):
  
    # A direct index table to see if sum % N
    # has appeared before or not. 
    modIdx = [0 for i in range(N)] 
  
    # initialize all mod index with -1
    for i in range(N):
        modIdx[i] = -1
  
    # initializing minLen and curLen 
    # with larger values
    minLen = N + 1
    curLen = N + 1
  
    # To store sum of array elements
    sum = 0
  
    # looping for each value of array
    l = 0; r = 0
    for i in range(N):
      
        sum += arr[i]
        sum %= N
  
        # If this is the first time we have
        # got mod value as 0, then S(0, i) % N
        # == 0
        if (modIdx[sum] == -1 and sum == 0):
            curLen = i + 1
  
        # If we have reached this mod before then
        # length of subarray will be i - previous_position
        if (modIdx[sum] != -1):
            curLen = i - modIdx[sum]
  
        # choose minimum length os subarray till now
        if (curLen < minLen):
          
            minLen = curLen
  
            # update left and right indices of subarray
            l = modIdx[sum] + 1
            r = i
          
        modIdx[sum] = i
      
    # print subarray
    for i in range(l, r + 1):
        print(arr[i] , " ", end = "")
    print()
  
# Driver program
arr = [1, 1, 2, 2, 4, 2]
N = len(arr)
printSubarrayMultipleOfN(arr, N)
  
# This code is contributed by Anant Agarwal.

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to find subarray whose sum
// is multiple of size
using System;
class GFG {
      
    // Method prints smallest subarray whose sum is
    // multiple of size
    static void printSubarrayMultipleOfN(int []arr, 
                                            int N)
    {
          
        // A direct index table to see if sum % N
        // has appeared before or not.
        int []modIdx = new int[N];
  
        // initialize all mod index with -1
        for (int i = 0; i < N; i++)
            modIdx[i] = -1;
  
        // initializing minLen and curLen with 
        // larger values
        int minLen = N + 1;
        int curLen = N + 1;
  
        // To store sum of array elements
        int sum = 0;
  
        // looping for each value of array
        int l = 0, r = 0;
          
        for (int i = 0; i < N; i++) {
            sum += arr[i];
            sum %= N;
  
            // If this is the first time we 
            // have got mod value as 0, then 
            // S(0, i) % N == 0
            if (modIdx[sum] == -1 && sum == 0)
                curLen = i + 1;
  
            // If we have reached this mod before 
            // then length of subarray will be i 
            // - previous_position
            if (modIdx[sum] != -1)
                curLen = i - modIdx[sum];
  
            // choose minimum length os subarray 
            // till now
            if (curLen < minLen) {
                minLen = curLen;
  
                // update left and right indices 
                // of subarray
                l = modIdx[sum] + 1;
                r = i;
            }
              
            modIdx[sum] = i;
        }
  
        // print subarray
        for (int i = l; i <= r; i++)
            Console.Write(arr[i] + " ");
              
        Console.WriteLine();
    }
      
    // Driver Code
    public static void Main()
    {
        int []arr = {1, 1, 2, 2, 4, 2};
        int N = arr.Length;
  
        printSubarrayMultipleOfN(arr, N);
    }
}
  
// This code is contributed by nitin mittal.

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP program to find subarray
// whose sum is multiple of size
  
// Method prints smallest subarray 
// whose sum is multiple of size
function printSubarrayMultipleOfN($arr
                                  $N)
{
    // A direct index table to see 
    // if sum % N has appeared 
    // before or not. 
    $modIdx = array(); 
  
    // initialize all mod
    // index with -1
    for ($i = 0; $i < $N; $i++)
        $modIdx[$i] = -1;
  
    // initializing minLen and 
    // curLen with larger values
    $minLen = $N + 1;
    $curLen = $N + 1;
  
    // To store sum of
    // array elements
    $sum = 0;
  
    // looping for each 
    // value of array
    $l; $r;
    for ($i = 0; $i < $N; $i++)
    {
        $sum += $arr[$i];
        $sum %= $N;
  
        // If this is the first time 
        // we have got mod value as 0, 
        // then S(0, i) % N == 0
        if ($modIdx[$sum] == -1 && 
            $sum == 0)
            $curLen = $i + 1;
  
        // If we have reached this mod 
        // before then length of subarray 
        // will be i - previous_position
        if ($modIdx[$sum] != -1)
            $curLen = $i - $modIdx[$sum];
  
        // choose minimum length
        // as subarray till now
        if ($curLen < $minLen)
        {
            $minLen = $curLen;
  
            // update left and right
            // indices of subarray
            $l = $modIdx[$sum] + 1;
            $r = $i;
        }
        $modIdx[$sum] = $i;
    }
  
    // print subarray
    for ($i = $l; $i <= $r; $i++)
        echo $arr[$i] , " ";
    echo "\n" ;
}
  
// Driver Code
$arr = array(1, 1, 2, 2, 4, 2);
$N = count($arr);
  
printSubarrayMultipleOfN($arr, $N);
  
// This code is contributed by anuj_67.
?>

chevron_right



Output :

2 4

This article is contributed by Utkarsh Trivedi. 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 write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



My Personal Notes arrow_drop_up

Improved By : nitin mittal, vt_m



Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.