Open In App

Longest Subarray With Sum Divisible By K

Last Updated : 22 Apr, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an arr[] containing n integers and a positive integer k, he problem is to find the longest subarray's length with the sum of the elements divisible by k.

Examples:

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

Input: arr[] = [-2, 2, -5, 12, -11, -1, 7], k = 3
Output: 5
Explanation: The subarray [2, -5, 12, -11, -1], has sum = -3, which is divisible by 3.

Input: arr[] = [1, 2, -2], k = 5
Output: 2
Explanation: The subarray is [2, -2] with sum = 0, which is divisible by 2.

[Naive Approach] Using loop- Iterating over all subarrays

Consider all the subarray sums using two nested for loops and return the length of the longest subarray with a sum divisible by k. To avoid overflow while computing the sum of the subarray, we can keep track of (subarray sum % k) and if (subarray sum % k) results to 0, we can use its length to find the longest subarray divisible by k.

C++
// C++ Program to find the longest subarray with sum
// divisible by k by iterating over all subarrays

#include <iostream>
#include <vector>
using namespace std;

int longestSubarrayDivK(vector<int> &arr, int k) {
    int res = 0;
    for (int i = 0; i < arr.size(); i++) {

        // Initialize sum for the current subarray
        int sum = 0;
        for (int j = i; j < arr.size(); j++) {
          
            // Add the current element to the subarray sum
            sum = (sum + arr[j]) % k;

            // Update max length if sum is divisible by k
            if (sum == 0)
                res = max(res, j - i + 1);
        }
    }
    return res;
}

int main() {
    vector<int> arr = {2, 7, 6, 1, 4, 5};
    int k = 3;

    cout << longestSubarrayDivK(arr, k);
    return 0;
}
C
// C Program to find the longest subarray with sum
// divisible by k by iterating over all subarrays

#include <stdio.h>
int longestSubarrayDivK(int arr[], int n, int k) {
    int res = 0;
    for (int i = 0; i < n; i++) {
      
        // Initialize sum for the current subarray
        int sum = 0;
        for (int j = i; j < n; j++) {
          
            // Add the current element to the subarray sum
            sum = (sum + arr[j]) % k;

            // Update max length if sum is divisible by k
            if (sum == 0)
                res = (res > (j - i + 1)) ? res : (j - i + 1);
        }
    }
    return res;
}

int main() {
    int arr[] = {2, 7, 6, 1, 4, 5};
    int k = 3;
    int n = sizeof(arr) / sizeof(arr[0]);

    printf("%d\n", longestSubarrayDivK(arr, n, k));
    return 0;
}
Java
// Java Program to find the longest subarray with sum
// divisible by k by iterating over all subarrays

import java.util.*;
class GfG {
    static int longestSubarrayDivK(int[] arr, int k) {
        int res = 0;
        for (int i = 0; i < arr.length; i++) {
            // Initialize sum for the current subarray
            int sum = 0;
            for (int j = i; j < arr.length; j++) {
                // Add the current element to the subarray sum
                sum = (sum + arr[j]) % k; 

                // Update max length if sum is divisible by k
                if (sum == 0)
                    res = Math.max(res, j - i + 1);
            }
        }
        return res;
    }

    public static void main(String[] args) {
        int[] arr = {2, 7, 6, 1, 4, 5};
        int k = 3;

        System.out.println(longestSubarrayDivK(arr, k));
    }
}
Python
# Python Program to find the longest subarray with sum
# divisible by k by iterating over all subarrays

def longestSubarrayDivK(arr, k):
    res = 0
    for i in range(len(arr)):
        # Initialize sum for the current subarray
        sum = 0
        for j in range(i, len(arr)):
            # Add the current element to the subarray sum
            sum = (sum + arr[j]) % k; 

            # Update max length if sum is divisible by k
            if sum == 0:
                res = max(res, j - i + 1)
    return res

if __name__ == "__main__":
    arr = [2, 7, 6, 1, 4, 5]
    k = 3

    print(longestSubarrayDivK(arr, k))
C#
// C# Program to find the longest subarray with sum
// divisible by k by iterating over all subarrays

using System;

class GfG {
    static int longestSubarrayDivK(int[] arr, int k) {
        int res = 0;
        for (int i = 0; i < arr.Length; i++) {
            
            // Initialize sum for the current subarray
            int sum = 0;
            for (int j = i; j < arr.Length; j++) {
                
                // Add the current element to the subarray sum
                sum = (sum + arr[j]) % k; 

                // Update max length if sum is divisible by k
                if (sum == 0)
                    res = Math.Max(res, j - i + 1);
            }
        }
        return res;
    }

    static void Main(string[] args) {
        int[] arr = {2, 7, 6, 1, 4, 5};
        int k = 3;

        Console.WriteLine(longestSubarrayDivK(arr, k));
    }
}
JavaScript
// JavaScript Program to find the longest subarray with sum
// divisible by k by iterating over all subarrays

function longestSubarrayDivK(arr, k) {
    let res = 0;
    for (let i = 0; i < arr.length; i++) {
        
        // Initialize sum for the current subarray
        let sum = 0;
        for (let j = i; j < arr.length; j++) {
            
            // Add the current element to the subarray sum
            sum = (sum + arr[j]) % k; 

            // Update max length if sum is divisible by k
            if (sum === 0)
                res = Math.max(res, j - i + 1);
        }
    }
    return res;
}

// Driver Code
const arr = [2, 7, 6, 1, 4, 5];
const k = 3;

console.log(longestSubarrayDivK(arr, k));

Output
4

Time Complexity: O(n^2)
Auxiliary Space: O(1)

[Expected Approach] Using Prefix Sum modulo k

The idea is to use Prefix Sum Technique along with Hashing. On observing carefully, we can say that if a subarray arr[i…j] has sum divisible by k, then (prefix sum[i] % k) will be equal to the (prefix sum[j] % k). So, we can iterate over arr[] while maintaining a hash map or dictionary to keep track of the first occurrence of of (prefix sum % k) at each index. For each index i, the longest subarray ending at i and having sum divisible by k will be equal to i - first occurrence of (prefix sum[i] % k).

Note: Negative value of (prefix sum mod k) needs to be handled separately in languages like C++, Java, C# and JavaScript, whereas in Python (prefix sum mod k) is always a non-negative value as it takes the sign of the divisor, that is k.

C++
// C++ Code to find longest Subarray With Sum Divisible
// By K using Prefix Sum and Hash map

#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;

int longestSubarrayDivK(vector<int> &arr, int k) {
    int n = arr.size(), res = 0;
    unordered_map<int, int> prefIdx;
    int sum = 0;

    // Iterate over all ending points
    for (int i = 0; i < n; i++) {

        // prefix sum mod k (handling negative prefix sum)
        sum = ((sum + arr[i]) % k + k) % k;

        // If sum == 0, then update result with the
        // length of subarray arr[0...i]
        if (sum == 0)
            res = i + 1;

        // Update max length for repeating sum
        else if (prefIdx.find(sum) != prefIdx.end()) {
            res = max(res, i - prefIdx[sum]);
        }

        // Store the first occurrence of sum
        else {
            prefIdx[sum] = i;
        }
    }
    return res;
}

int main() {
    vector<int> arr = {2, 7, 6, 1, 4, 5};
    int k = 3;

    cout << longestSubarrayDivK(arr, k);
}
Java
// Java Code to find longest Subarray With Sum Divisible
// By K using Prefix Sum and Hash map

import java.util.HashMap;
import java.util.Map;

class GfG {
    static int longestSubarrayDivK(int[] arr, int k) {
        int n = arr.length, res = 0;
        Map<Integer, Integer> prefIdx = new HashMap<>();
        int sum = 0;

        // Iterate over all ending points
        for (int i = 0; i < n; i++) {

            // prefix sum mod k (handling negative prefix sum)
            sum = ((sum + arr[i]) % k + k) % k;

            // If sum == 0, then update result with the
            // length of subarray arr[0...i]
            if (sum == 0)
                res = i + 1;

            // Update max length for repeating sum
            else if (prefIdx.containsKey(sum)) {
                res = Math.max(res, i - prefIdx.get(sum));
            }

            // Store the first occurrence of sum
            else {
                prefIdx.put(sum, i);
            }
        }
        return res;
    }

    public static void main(String[] args) {
        int[] arr = {2, 7, 6, 1, 4, 5};
        int k = 3;

        System.out.println(longestSubarrayDivK(arr, k));
    }
}
Python
# Python Code to find longest Subarray With Sum Divisible
# By K using Prefix Sum and Hash map

def longestSubarrayDivK(arr, k):
    n = len(arr)
    res = 0
    prefIdx = {}
    sum = 0

    # Iterate over all ending points
    for i in range(n):

        # prefix sum mod k 
        sum = (sum + arr[i]) % k

        # If sum == 0, then update result with the
        # length of subarray arr[0...i]
        if sum == 0:
            res = i + 1

        # Update max length for repeating sum
        elif sum in prefIdx:
            res = max(res, i - prefIdx[sum])

        # Store the first occurrence of sum
        else:
            prefIdx[sum] = i

    return res

if __name__ == "__main__":
	arr = [2, 7, 6, 1, 4, 5]
	k = 3

	print(longestSubarrayDivK(arr, k))
C#
// C# Code to find longest Subarray With Sum Divisible
// By K using Prefix Sum and Hash map

using System;
using System.Collections.Generic;

class GfG {
    static int LongestSubarrayDivK(int[] arr, int k) {
        int n = arr.Length, res = 0;
        Dictionary<int, int> prefIdx = new Dictionary<int, int>();
        int sum = 0;

        // Iterate over all ending points
        for (int i = 0; i < n; i++) {
          
            // prefix sum mod k (handling negative prefix sum)
            sum = ((sum + arr[i]) % k + k) % k;

            // If sum == 0, then update result with the
            // length of subarray arr[0...i]
            if (sum == 0)
                res = i + 1;

            // Update max length for repeating sum
            else if (prefIdx.ContainsKey(sum)) {
                res = Math.Max(res, i - prefIdx[sum]);
            }

            // Store the first occurrence of sum
            else {
                prefIdx[sum] = i;
            }
        }
        return res;
    }

    static void Main() {
        int[] arr = {2, 7, 6, 1, 4, 5};
        int k = 3;

        Console.WriteLine(LongestSubarrayDivK(arr, k));
    }
}
JavaScript
// JavaScript Code to find longest Subarray With Sum Divisible
// By K using Prefix Sum and Hash map

function longestSubarrayDivK(arr, k) {
    let n = arr.length, res = 0;
    let prefIdx = new Map();
    let sum = 0;

    // Iterate over all ending points
    for (let i = 0; i < n; i++) {

        // prefix sum mod k (handling negative prefix sum)
        sum = ((sum + arr[i]) % k + k) % k;

        // If sum == 0, then update result with the
        // length of subarray arr[0...i]
        if (sum === 0)
            res = i + 1;

        // Update max length for repeating sum
        else if (prefIdx.has(sum)) {
            res = Math.max(res, i - prefIdx.get(sum));
        }

        // Store the first occurrence of sum
        else {
            prefIdx.set(sum, i);
        }
    }
    return res;
}

// Driver Code
let arr = [2, 7, 6, 1, 4, 5];
let k = 3;

console.log(longestSubarrayDivK(arr, k));

Output
4

Time Complexity: O(n), as we are iterating over the array only once.
Auxiliary Space: O(min(n, k)), as at most keys can be present in the hash map or dictionary.