Open In App
Related Articles

Longest subarray with sum divisible by K

Improve Article
Improve
Save Article
Save
Like Article
Like

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 = 3
Output: 4
Explanation: 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 = 3
Output: 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. 

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 longestSubarrWthSumDivByK(int arr[], int N, int k)
{
         int maxl=0;
        for(int i=0;i<N;i++)
        {
            int sum1 = 0;
            for(int j=i;j<N;j++)
            {
                sum1+=arr[j];
                if(sum1 % k == 0)
                {
                    maxl = max(maxl , j - i + 1);
                }
                 
            }
        }
 
        return maxl;
}
 
// Driver code
int 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;
}
 
// This code is contributed by Arpit Jain


Java




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)
  {
    int maxl = 0;
    for (int i = 0; i < N; i++) {
      int sum1 = 0;
      for (int j = i; j < N; j++) {
        sum1 += arr[j];
        if (sum1 % k == 0)
          maxl = Math.max(maxl, j - i + 1);
      }
    }
 
    return maxl;
  }
 
  // Driver code
  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 Ajax


C#




// C# implementation to find the longest subarray
// with sum divisible by k
 
using System;
 
class GFG {
 
    // function to find the longest subarray
    // with sum divisible by k
    static int longestSubarrWthSumDivByK(int[] arr, int N,
                                         int k)
    {
        int maxl = 0;
        for (int i = 0; i < N; i++) {
            int sum1 = 0;
            for (int j = i; j < N; j++) {
                sum1 += arr[j];
                if (sum1 % k == 0)
                    maxl = Math.Max(maxl, j - i + 1);
            }
        }
 
        return maxl;
    }
 
    // Driver code
    public static void Main(string[] args)
    {
        int[] arr = { 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 Karandeep1234


Python3




# Python3 implementation to find the longest subarray
# with sum divisible by k
 
def longestSubarrWthSumDivByK(arr, N, k):
    maxl = 0
    for i in range(N):
        sum1 = 0
        for j in range(i, N):
            sum1 += arr[j]
            if sum1 % k == 0:
                maxl = max(maxl, j - i + 1)
    return maxl
 
# Driver code
arr = [2, 7, 6, 1, 4, 5]
n = len(arr)
k = 3
 
print("Length =", longestSubarrWthSumDivByK(arr, n, k))


Javascript




// JavaScript implementation to find the longest subarray
// with sum divisible by k
function longestSubarrWthSumDivByK(arr, N, k) {
    let maxl = 0;
    for (let i = 0; i < N; i++) {
        let sum1 = 0;
        for (let j = i; j < N; j++) {
            sum1 += arr[j];
            if (sum1 % k === 0) {
                maxl = Math.max(maxl, j - i + 1);
            }
        }
    }
    return maxl;
}
 
// Driver code
let arr = [ 2, 7, 6, 1, 4, 5 ];
let N = arr.length;
let k = 3;
console.log("Length = " + longestSubarrWthSumDivByK(arr, N, k));
 
//This code is contributed by dhanshri borse


Output

Length = 4

Time Complexity: O(n2).
Auxiliary Space: O(1)

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.

  1. If mod_arr[i] == 0, then update max_len = (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 hash table’s value associated with mod_arr[i]. Let this be i.
  4. If maxLen < (i – idx), then update max_len = (i – idx).
  5. Finally, return max_len.

Below is the implementation of the above approach:

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 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 code
int 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




// 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 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




# 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 Code
if __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


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
    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


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 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 above
var 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>


Output

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 of the above approach:

C++




#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;
 
    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 code
int 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




/*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 negative 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


Python3




# function to find the longest subarray
#  with sum divisible by k
 
 
def 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 = 3
print("Length =", longestSubarrWthSumDivByK(arr, n, k))
 
# This code is contributed by amreshkumar3, and updated by Kshitij Dwivedi


C#




using System;
using System.Collections.Generic;
 
// C# implementation to find the longest
// subarray with sum divisible by k
public 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


Javascript




<script>
// function to find the longest subarray
// with sum divisible by k
function 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_len;
}
 
// 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>


Output

Length = 4

Time Complexity: O(n), as we traverse the input array only once.
Auxiliary Space: O(min(n,k))


Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!

Last Updated : 02 Feb, 2023
Like Article
Save Article
Previous
Next
Similar Reads
Complete Tutorials