Skip to content
Related Articles

Related Articles

Improve Article

Longest subarray with sum divisible by k

  • Difficulty Level : Hard
  • Last Updated : 20 May, 2021

Given an arr[] containing n integers and a positive integer k. The problem is to find the length of the longest subarray with sum of the elements divisible by the given value k.
Examples:

Input : arr[] = {2, 7, 6, 1, 4, 5}, k = 3
Output : 4
The subarray is {7, 6, 1, 4} with sum 18,
which is divisible by 3.

Input : arr[] = {-2, 2, -5, 12, -11, -1, 7}
Output : 5

Method 1 (Naive Approach): Consider all the subarrays and return the length of the subarray with sum divisible by k and has the longest length. 
Time Complexity: O(n2).
Method 2 (Efficient Approach): Create an array mod_arr[] where mod_arr[i] stores (sum(arr[0]+arr[1]..+arr[i]) % k). Create a hash table having tuple as (ele, idx), where ele represents an element of mod_arr[] and idx represents the element’s index of first occurrence in mod_arr[]. Now, traverse mod_arr[] from i = 0 to n and follow the steps given below.

  1. If mod_arr[i] == 0, then update maxLen = (i + 1).
  2. Else if mod_arr[i] is not present in the hash table, then create tuple (mod_arr[i], i) in the hash table.
  3. Else, get the value associated with mod_arr[i] in the hash table. Let this be idx.
  4. If maxLen < (i – idx), then update maxLen = (i – idx).

Finally return maxLen.

C++




// C++ implementation to find the longest subarray
// with sum divisible by k
#include <bits/stdc++.h>
 
using namespace std;
 
// function to find the longest subarray
// with sum divisible by k
int longSubarrWthSumDivByK(int arr[],
                          int n, int k)
{
    // unodered map 'um' implemented as
    // hash table
    unordered_map<int, int> um;
     
    // 'mod_arr[i]' stores (sum[0..i] % k)
    int mod_arr[n], max = 0;
    int curr_sum = 0;
     
    // traverse arr[] and build up the
    // array 'mod_arr[]'
    for (int i = 0; i < n; i++)
    {
        curr_sum += arr[i];
         
        // as the sum can be negative, taking modulo twice
        mod_arr[i] = ((curr_sum % k) + k) % k;       
    }   
     
    for (int i = 0; i < n; i++)
    {
        // if true then sum(0..i) is divisible
        // by k
        if (mod_arr[i] == 0)
            // update 'max'
            max = i + 1;
         
        // if value 'mod_arr[i]' not present in 'um'
        // then store it in 'um' with index of its
        // first occurrence       
        else if (um.find(mod_arr[i]) == um.end())
            um[mod_arr[i]] = i;
             
        else
            // if true, then update 'max'
            if (max < (i - um[mod_arr[i]]))
                max = i - um[mod_arr[i]];           
    }
     
    // required length of longest subarray with
    // sum divisible by 'k'
    return max;
}                         
 
// Driver program to test above
int main()
{
    int arr[] = {2, 7, 6, 1, 4, 5};
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = 3;
     
    cout << "Length = "
         << longSubarrWthSumDivByK(arr, n, k);
          
    return 0;    
}

Java




// Java implementation to find the longest
// subarray with sum divisible by k
import java.io.*;
import java.util.*;
 
class GfG {
         
    // function to find the longest subarray
    // with sum divisible by k
    static int longSubarrWthSumDivByK(int arr[],
                                      int n, int k)
    {
        // unodered map 'um' implemented as
        // hash table
        HashMap<Integer, Integer> um= new HashMap<Integer, Integer>();
         
        // 'mod_arr[i]' stores (sum[0..i] % k)
        int mod_arr[]= new int[n];
        int max = 0;
        int curr_sum = 0;
         
        // traverse arr[] and build up the
        // array 'mod_arr[]'
        for (int i = 0; i < n; i++)
        {
            curr_sum += arr[i];
             
            // as the sum can be negative,
            // taking modulo twice
            mod_arr[i] = ((curr_sum % k) + k) % k;    
        }
         
        for (int i = 0; i < n; i++)
        {
            // if true then sum(0..i) is
            // divisible by k
            if (mod_arr[i] == 0)
                // update 'max'
                max = i + 1;
             
            // if value 'mod_arr[i]' not present in 'um'
            // then store it in 'um' with index of its
            // first occurrence    
            else if (um.containsKey(mod_arr[i]) == false)
                um.put(mod_arr[i] , i);
                 
            else
                // if true, then update 'max'
                if (max < (i - um.get(mod_arr[i])))
                    max = i - um.get(mod_arr[i]);        
        }
         
        // required length of longest subarray with
        // sum divisible by 'k'
        return max;
    }   
     
    public static void main (String[] args)
    {
        int arr[] = {2, 7, 6, 1, 4, 5};
        int n = arr.length;
        int k = 3;
         
        System.out.println("Length = "+
                            longSubarrWthSumDivByK(arr, n, k));
         
    }
}
 
// This code is contributed by Gitanjali.

Python3




# Python3 implementation to find the
# longest subarray with sum divisible by k
 
# Function to find the longest
# subarray with sum divisible by k
def longSubarrWthSumDivByK(arr, n, k):
     
    # unodered map 'um' implemented
    # as hash table
    um = {}
 
    # 'mod_arr[i]' stores (sum[0..i] % k)
    mod_arr = [0 for i in range(n)]
    max = 0
    curr_sum = 0
     
    # Traverse arr[] and build up
    # the array 'mod_arr[]'
    for i in range(n):
        curr_sum += arr[i]
         
        # As the sum can be negative,
        # taking modulo twice
        mod_arr[i] = ((curr_sum % k) + k) % k
     
    for i in range(n):
         
        # If true then sum(0..i) is
        # divisible by k
        if (mod_arr[i] == 0):
             
            # Update 'max'
            max = i + 1
         
        # If value 'mod_arr[i]' not present in
        # 'um' then store it in 'um' with index
        # of its first occurrence
        elif (mod_arr[i] not in um):
            um[mod_arr[i]] = i
             
        else:
             
            # If true, then update 'max'
            if (max < (i - um[mod_arr[i]])):
                max = i - um[mod_arr[i]]        
     
    # Required length of longest subarray
    # with sum divisible by 'k'
    return max   
 
# Driver Code
if __name__ == '__main__':
     
    arr = [ 2, 7, 6, 1, 4, 5 ]
    n = len(arr)
    k = 3
     
    print("Length =",
           longSubarrWthSumDivByK(arr, n, k))
     
# This code is contributed by
# Surendra_Gangwar

C#




using System;
using System.Collections.Generic;
 
// C# implementation to find the longest 
// subarray with sum divisible by k
 
public class GfG
{
 
    // function to find the longest subarray
    // with sum divisible by k
    public static int longSubarrWthSumDivByK(int[] arr, int n, int k)
    {
        // unodered map 'um' implemented as
        // hash table
        Dictionary<int, int> um = new Dictionary<int, int>();
 
        // 'mod_arr[i]' stores (sum[0..i] % k)
        int[] mod_arr = new int[n];
        int max = 0;
        int curr_sum = 0;
 
        // traverse arr[] and build up the
        // array 'mod_arr[]'
        for (int i = 0; i < n; i++)
        {
            curr_sum += arr[i];
 
            // as the sum can be negative, 
            // taking modulo twice
            mod_arr[i] = ((curr_sum % k) + k) % k;
        }
 
        for (int i = 0; i < n; i++)
        {
            // if true then sum(0..i) is 
            // divisible by k
            if (mod_arr[i] == 0)
            {
                // update 'max'
                max = i + 1;
            }
 
            // if value 'mod_arr[i]' not present in 'um'
            // then store it in 'um' with index of its
            // first occurrence     
            else if (um.ContainsKey(mod_arr[i]) == false)
            {
                um[mod_arr[i]] = i;
            }
 
            else
            {
                // if true, then update 'max'
                if (max < (i - um[mod_arr[i]]))
                {
                    max = i - um[mod_arr[i]];
                }
            }
        }
 
        // required length of longest subarray with
        // sum divisible by 'k'
        return max;
    }
 
    public static void Main(string[] args)
    {
        int[] arr = new int[] {2, 7, 6, 1, 4, 5};
        int n = arr.Length;
        int k = 3;
 
        Console.WriteLine("Length = " + longSubarrWthSumDivByK(arr, n, k));
 
    }
}
 
// This code is contributed by Shrikant13

Javascript




<script>
 
// Javascript implementation to find the longest subarray
// with sum divisible by k
 
// function to find the longest subarray
// with sum divisible by k
function longSubarrWthSumDivByK(arr,  n, k)
{
    // unodered map 'um' implemented as
    // hash table
    var um = new Map();
     
    // 'mod_arr[i]' stores (sum[0..i] % k)
    var mod_arr = Array(n), max = 0;
    var curr_sum = 0;
     
    // traverse arr[] and build up the
    // array 'mod_arr[]'
    for (var i = 0; i < n; i++)
    {
        curr_sum += arr[i];
         
        // as the sum can be negative, taking modulo twice
        mod_arr[i] = ((curr_sum % k) + k) % k;       
    }   
     
    for (var i = 0; i < n; i++)
    {
        // if true then sum(0..i) is divisible
        // by k
        if (mod_arr[i] == 0)
            // update 'max'
            max = i + 1;
         
        // if value 'mod_arr[i]' not present in 'um'
        // then store it in 'um' with index of its
        // first occurrence       
        else if (!um.has(mod_arr[i]))
            um.set(mod_arr[i] , i);
             
        else
            // if true, then update 'max'
            if (max < (i - um.get(mod_arr[i])))
                max = i - um.get(mod_arr[i]);           
    }
     
    // required length of longest subarray with
    // sum divisible by 'k'
    return max;
}                         
 
// Driver program to test above
var arr = [2, 7, 6, 1, 4, 5];
var n = arr.length;
var k = 3;
 
document.write( "Length = "
     + longSubarrWthSumDivByK(arr, n, k));
      
// This code is contributed by rrrtnx.
</script>

Output:

Length = 4 

Time Complexity: O(n). 
Auxiliary Space: O(n^2).
Time complexity of this method can be improved by using an array of size equal to k for O(1) lookup since all elements would be less than k after using modulo operation on elements of input array.
 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :