Longest subarray with sum divisible by K

17 Jun, 2022
Given an arr[] containing n integers and a positive integer k. The problem is to find the longest subarray’s length with the sum of the elements divisible by the given value k.Examples:
Input: arr[] = {2, 7, 6, 1, 4, 5}, k = 3Output: 4Explaination: The subarray is {7, 6, 1, 4} with sum 18, which is divisible by 3.
Input: arr[] = {-2, 2, -5, 12, -11, -1, 7}, k = 3Output: 5
Method 1 (Naive Approach): Consider all the subarrays and return the length of the subarray with a sum divisible by k that 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, i), where ele represents an element of mod_arr[] and i 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.
If mod_arr[i] == 0, then update max_len = (i + 1).Else if mod_arr[i] is not present in the hash table, then create tuple (mod_arr[i], i) in the hash table.Else, get the hash table’s value associated with mod_arr[i]. Let this be i.If maxLen < (i – idx), then update max_len = (i – idx).Finally, return max_len.
If mod_arr[i] == 0, then update max_len = (i + 1).
Else if mod_arr[i] is not present in the hash table, then create tuple (mod_arr[i], i) in the hash table.
Else, get the hash table’s value associated with mod_arr[i]. Let this be i.
If maxLen < (i – idx), then update max_len = (i – idx).
Finally, return max_len.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// 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 longestSubarrWthSumDivByK(int arr[], int n, int k){    // unordered map 'um' implemented as    // hash table    unordered_map<int, int> um;         // 'mod_arr[i]' stores (sum[0..i] % k)    int mod_arr[n], max_len = 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;                // if true then sum(0..i) is divisible by k        if (mod_arr[i] == 0)            // update 'max'            max_len = 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_len < (i - um[mod_arr[i]]))                max_len = i - um[mod_arr[i]];               }         // return the required length of longest subarray    // with sum divisible by 'k'    return max_len;}                          // Driver codeint main(){    int arr[] = {2, 7, 6, 1, 4, 5};    int n = sizeof(arr) / sizeof(arr[0]);    int k = 3;         cout << "Length = "         << longestSubarrWthSumDivByK(arr, n, k);              return 0;    } // Code updated by Kshitij Dwivedi
// Java implementation to find the longest// subarray with sum divisible by kimport java.io.*;import java.util.*; class GfG {             // function to find the longest subarray    // with sum divisible by k    static int longestSubarrWthSumDivByK(int arr[], int n, int k)    {        // unordered 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_len = 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;                 // if true then sum(0..i) is            // divisible by k            if (mod_arr[i] == 0)                // update 'max'                max_len = 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_len < (i - um.get(mod_arr[i])))                    max_len = i - um.get(mod_arr[i]);                }                 // return the required length of longest subarray        // with sum divisible by 'k'        return max_len;    }            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 = "+                            longestSubarrWthSumDivByK(arr, n, k));             }} // This code is contributed by Gitanjali, updated by Kshitij Dwivedi
# Python3 implementation to find the# longest subarray with sum divisible by k # Function to find the longest# subarray with sum divisible by k def longestSubarrWthSumDivByK(arr, n, k):         # unordered map 'um' implemented    # as hash table    um = {}     # 'mod_arr[i]' stores (sum[0..i] % k)    mod_arr = [0 for i in range(n)]    max_len = 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         # If true then sum(0..i) is        # divisible by k        if (mod_arr[i] == 0):                         # Update 'max_len'            max_len = 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_len'            if (max_len < (i - um[mod_arr[i]])):                max_len = i - um[mod_arr[i]]                 # Return the required length of longest subarray    # with sum divisible by 'k'    return max_len    # Driver Codeif __name__ == '__main__':         arr = [2, 7, 6, 1, 4, 5]    n = len(arr)    k = 3         print("Length =",           longestSubarrWthSumDivByK(arr, n, k))     # This code is contributed by Surendra_Gangwar, updated by Kshitij Dwivedi
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 longestSubarrWthSumDivByK(int[] arr, int n, int k)    {        // unordered 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_len = 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,             // adjusting and calculating modulo twice            mod_arr[i] = ((curr_sum % k) + k) % k;             // if true then sum(0..i) is             // divisible by k            if (mod_arr[i] == 0)            {                // update 'max_len'                max_len = 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_len'                if (max_len < (i - um[mod_arr[i]]))                {                    max_len = i - um[mod_arr[i]];                }            }        }         // return the required length of longest subarray with        // sum divisible by 'k'        return max_len;    }     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 = " + longestSubarrWthSumDivByK(arr, n, k));     }} // This code is contributed by Shrikant13, updated by Kshitij Dwivedi
<script> // Javascript implementation to find the longest subarray// with sum divisible by k // function to find the longest subarray// with sum divisible by kfunction longestSubarrWthSumDivByK(arr, n, k){    // unordered map 'um' implemented as    // hash table    var um = new Map();         // 'mod_arr[i]' stores (sum[0..i] % k)    var mod_arr = Array(n), max_len = 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;                // if true then sum(0..i) is divisible        // by k        if (mod_arr[i] == 0)            // update 'max_len'            max_len = 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_len'            if (max_len < (i - um.get(mod_arr[i])))                max_len = i - um.get(mod_arr[i]);               }         // return the required length of longest subarray with    // sum divisible by 'k'    return max_len;}                          // Driver program to test abovevar arr = [2, 7, 6, 1, 4, 5];var n = arr.length;var k = 3; document.write( "Length = "     + longestSubarrWthSumDivByK(arr, n, k));      // This code is contributed by rrrtnx, and updated by Kshitij Dwivedi</script>
Length = 4
Time Complexity: O(n), as we traverse the input array only once.Auxiliary Space: O(n * k), O(n) for mod_arr[], and O(k) for storing the remainder values in the hash table.
Space Optimized approach: The space optimization for the above approach to O(n) Instead of keeping a separate array to store the modulus of all values, we compute it on the go and store remainders in the hash table.Below is the implementation:
C++
Java
Python3
C#
Javascript
#include <bits/stdc++.h> using namespace std; // function to find the longest subarray// with sum divisible by kint longestSubarrWthSumDivByK(int arr[], int n, int k){    // unordered map 'um' implemented as    // hash table    unordered_map<int, int> um;     int max_len = 0;    int curr_sum = 0;     for (int i = 0; i < n; i++)    {        curr_sum += arr[i];         int mod = ((curr_sum % k) + k) % k;               // if true then sum(0..i) is divisible        // by k        if (mod == 0)            // update 'max_len'            max_len = 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) == um.end())            um[mod] = i;         else            // if true, then update 'max_len'            if (max_len < (i - um[mod]))                max_len = i - um[mod];    }     // return the required length of longest subarray with    // sum divisible by 'k'    return max_len;} // Driver codeint main(){    int arr[] = {2, 7, 6, 1, 4, 5};    int n = sizeof(arr) / sizeof(arr[0]);    int k = 3;     cout << "Length = " << longestSubarrWthSumDivByK(arr, n, k);     return 0;} // Code Updated by Kshitij Dwivedi
/*package whatever //do not write package name here */ import java.io.*;import java.util.*; class GFG {    static int longestSubarrWthSumDivByK(int arr[], int n, int k)    {        Map<Integer, Integer> map = new HashMap<>();               int max_len = 0;        int sum = 0;               for (int i = 0; i < n; i++)        {            sum += arr[i];                       // to handle negavtive values as well            int mod = ((sum % k) + k) % k;             if (mod == 0)                max_len = i + 1;             if (!map.containsKey(mod))                map.put(mod, i);            else            {                int sz = i - map.get(mod);                max_len = Math.max(max_len, sz);            }        }         return max_len;    }     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 = " + longestSubarrWthSumDivByK(arr, n, k));    }} // Updated By Kshitij Dwivedi
# function to find the longest subarray#  with sum divisible by kdef longestSubarrWthSumDivByK(arr, n, k):       # unordered map 'um' implemented as    # hash table    um = {}     max_len = 0    curr_sum = 0     for i in range(n):               curr_sum += arr[i]        mod = ((curr_sum % k) + k) % k        # if true then sum(0..i) is divisible by k                 if mod == 0:            # update 'max_len'            max_len = i + 1                     # if value 'mod_arr[i]' not present in 'um'        # then store it in 'um' with index of its        # first occurrence        elif mod in um.keys():            if max_len < (i - um[mod]):                max_len = i - um[mod]         else:            um[mod] = i     # return the required length of longest subarray with    # sum divisible by 'k'    return max_len   arr = [2, 7, 6, 1, 4, 5]n = len(arr)k = 3print("Length =", longestSubarrWthSumDivByK(arr, n, k)) # This code is contributed by amreshkumar3, and updated by Kshitij Dwivedi
using System;using System.Collections.Generic; // C# implementation to find the longest// subarray with sum divisible by kpublic class GFG {     public static int longestSubarrWthSumDivByK(int[] arr,                                             int n, int k)    {        // unordered map 'um' implemented as        // hash table        Dictionary<int, int> um = new Dictionary<int, int>();         int max_len = 0;        int curr_sum = 0;         for (int i = 0; i < n; i++)        {            curr_sum += arr[i];             int mod = ((curr_sum % k) + k) % k;                       // if true then sum(0..i) is divisible            // by k            if (mod == 0)               // update 'max_len'            {                max_len = i + 1;            }             // if value 'mod' not present in 'um'            // then store it in 'um' with index of its            // first occurrence            else if (um.ContainsKey(mod) == false)            {                um[mod] = i;            }             else            {                  // if true, then update 'max'                if (max_len < (i - um[mod]))                {                    max_len = i - um[mod];                }            }        }        // return the required length of longest subarray with        // sum divisible by 'k'        return max_len;    }       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 = " + longestSubarrWthSumDivByK(arr, n, k));    }} // This code is contributed by ishankhandelwals and updated by Kshitij Dwivedi
<script>// function to find the longest subarray// with sum divisible by kfunction longestSubarrWthSumDivByK(arr,n,k){    // map 'um' implemented as    // hash table    let um = new Map();     let max_len = 0;    let curr_sum = 0;     for (let i = 0; i < n; i++)    {        curr_sum += arr[i];         let mod = ((curr_sum % k) + k) % k;        // if true then sum(0..i) is divisible        // by k        if (mod == 0)            // update 'max_len'            max_len = 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) == false)            um.set(mod,i);         else            // if true, then update 'max'            if (max_len < (i - um.get(mod)))            max_len = i - um.get(mod);    }     // required length of longest subarray with    // sum divisible by 'k'    return max;} // Driver program to test above let arr = [2, 7, 6, 1, 4, 5];let n = arr.length;let k = 3; document.write("Length = " + longestSubarrWthSumDivByK(arr, n, k)); // This code is contributed by shinjanpatra, and updated by Kshitij Dwivedi.</script>
Length = 4
Time Complexity: O(n), as we traverse the input array only once.Auxiliary Space: O(n)
rex_wulf
shrikanth13
SURENDRA_GANGWAR
throne1032
1999shaswat
rrrtnx
surindertarika1234
ayush123ngp
amreshkumar3
shinjanpatra
ishankhandelwals
kshitijdwivedi28
harendrakumar123
Snapdeal
subarray
subarray-sum
Arrays
Hash
Snapdeal
Arrays
Hash
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.