Open In App

Count Subarrays With Sum Divisible By K

Last Updated : 15 Jan, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an array arr[] and an integer k, the task is to count all subarrays whose sum is divisible by k.

Examples:

Input: arr[] = [4, 5, 0, -2, -3, 1], k = 5
Output: 7
Explanation: There are 7 subarrays whose sum is divisible by 5: [4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3] and [-2, -3].

Input: arr[] = [2, 2, 2, 2, 2, 2], k = 2
Output: 21
Explanation: All subarray sums are divisible by 2.

Input: arr[] = [-1, -3, 2], k = 5
Output: 0
Explanation: There is no subarray whose sum is divisible by k.

[Naive Approach] Iterating over all subarrays

The idea is to iterate over all possible subarrays while keeping the track of the sum of subarray modulo k. For any subarray, if the sub of subarray modulo k becomes 0, increment the count by 1. After iterating over all the subarrays, return the count as result.

C++
// C++ Code to Count Subarrays With Sum Divisible By K
// by iterating over all possible subarrays

#include <iostream>
#include <vector>

using namespace std;

int subCount(vector<int> &arr, int k) {
	int n = arr.size(), res = 0;	
  
	// Iterating over starting indices of subarray
	for(int i = 0; i < n; i++) {
    	int sum = 0;
      
		// Iterating over ending indices of subarray
        for(int j = i; j < n; j++) {
        	sum = (sum + arr[j]) % k;
            if(sum == 0)
                res += 1;
        }
    }
	return res;
}

int main() {
	vector<int> arr = {4, 5, 0, -2, -3, 1};
    int k = 5;
    
    cout << subCount(arr, k);
}
C
// C Code to Count Subarrays With Sum Divisible By K
// by iterating over all possible subarrays

#include <stdio.h>

int subCount(int arr[], int n, int k) {
    int res = 0;

    // Iterating over starting indices of subarray
    for (int i = 0; i < n; i++) {
        int sum = 0;

        // Iterating over ending indices of subarray
        for (int j = i; j < n; j++) {
            sum = (sum + arr[j]) % k;
            if (sum == 0)
                res += 1;
        }
    }
    return res;
}

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

    printf("%d", subCount(arr, n, k));
    return 0;
}
Java
// Java Code to Count Subarrays With Sum Divisible By K
// by iterating over all possible subarrays

import java.util.*;

class GfG {
    static int subCount(int[] arr, int k) {
        int n = arr.length, res = 0;

        // Iterating over starting indices of subarray
        for (int i = 0; i < n; i++) {
            int sum = 0;

            // Iterating over ending indices of subarray
            for (int j = i; j < n; j++) {
                sum = (sum + arr[j]) % k;
                if (sum == 0)
                    res += 1;
            }
        }
        return res;
    }

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

        System.out.println(subCount(arr, k));
    }
}
Python
# Python Code to Count Subarrays With Sum Divisible By K
# by iterating over all possible subarrays

def subCount(arr, k):
    n = len(arr)
    res = 0
    
    # Iterating over starting indices of subarray
    for i in range(n):
        sum = 0
        
        # Iterating over ending indices of subarray
        for j in range(i, n):
            sum = (sum + arr[j]) % k
            if sum == 0:
                res += 1
                
    return res

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

	print(subCount(arr, k))
C#
// C# Code to Count Subarrays With Sum Divisible By K
// by iterating over all possible subarrays

using System;
using System.Collections.Generic;

class GfG {    
    static int subCount(int[] arr, int k) {
        int n = arr.Length, res = 0;

        // Iterating over starting indices of subarray
        for (int i = 0; i < n; i++) {
            int sum = 0;

            // Iterating over ending indices of subarray
            for (int j = i; j < n; j++) {
                sum = (sum + arr[j]) % k;
                if (sum == 0)
                    res += 1;
            }
        }
        return res;
    }

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

        Console.WriteLine(subCount(arr, k));
    }
}
JavaScript
// JavaScript Code to Count Subarrays With Sum Divisible By K
// by iterating over all possible subarrays

function subCount(arr, k) {
    let n = arr.length, res = 0;

    // Iterating over starting indices of subarray
    for (let i = 0; i < n; i++) {
        let sum = 0;

        // Iterating over ending indices of subarray
        for (let j = i; j < n; j++) {
            sum = (sum + arr[j]) % k;
            if (sum === 0)
                res += 1;
        }
    }
    return res;
}

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

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

Output
7

Time Complexity: O(n^2), as we are iterating over all possible starting and ending points of subarrays.
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 count the number of (prefix sum mod k). For each index i, the number of subarrays ending at i and having sum divisible by k will be equal to the count of occurrences of (prefix sum[i] mod k) before i.

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 Count Subarrays With Sum Divisible By K
// using Prefix Sum and Hash map

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

int subCount(vector<int> &arr, int k) {
	int n = arr.size(), res = 0;
	unordered_map<int, int> prefCnt;
	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 increment the result by 1
		// to count subarray arr[0...i]
        if(sum == 0)
        	res += 1;
      
        // Add count of all starting points for index i
		res += prefCnt[sum];
      
        prefCnt[sum] += 1;
    }
	return res;
}

int main() {
	vector<int> arr = {4, 5, 0, -2, -3, 1};
    int k = 5;
    
    cout << subCount(arr, k);
}
Java
// Java Code to Count Subarrays With Sum Divisible By K
// using Prefix Sum and Hash map

import java.util.*;

class GfG {
    static int subCount(int[] arr, int k) {
        int n = arr.length, res = 0;
        Map<Integer, Integer> prefCnt = 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 increment the result by 1
            // to count subarray arr[0...i]
            if (sum == 0)
                res += 1;

            // Add count of all starting points for index i
            res += prefCnt.getOrDefault(sum, 0);

            prefCnt.put(sum, prefCnt.getOrDefault(sum, 0) + 1);
        }
        return res;
    }

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

        System.out.println(subCount(arr, k));
    }
}
Python
# Python Code to Count Subarrays With Sum Divisible By K
# using Prefix Sum and Dictionary

from collections import defaultdict

def subCount(arr, k):
    n = len(arr)
    res = 0
    prefCnt = defaultdict(int)
    sum = 0

    # Iterate over all ending points
    for i in range(n):
        sum = (sum + arr[i]) % k

        # If sum == 0, then increment the result by 1
        # to count subarray arr[0...i]
        if sum == 0:
            res += 1

        # Add count of all starting points for index i
        res += prefCnt[sum]

        prefCnt[sum] += 1

    return res

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

	print(subCount(arr, k))
C#
// C# Code to Count Subarrays With Sum Divisible By K
// using Prefix Sum and Hash map

using System;
using System.Collections.Generic;

class GfG {
    static int SubCount(int[] arr, int k) {
        int n = arr.Length, res = 0;
        Dictionary<int, int> prefCnt = 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 increment the result by 1
            // to count subarray arr[0...i]
            if (sum == 0)
                res += 1;

            // Add count of all starting points for index i
            if (prefCnt.ContainsKey(sum))
                res += prefCnt[sum];

            if (prefCnt.ContainsKey(sum))
                prefCnt[sum] += 1;
            else
                prefCnt[sum] = 1;
        }
        return res;
    }

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

        Console.WriteLine(SubCount(arr, k));
    }
}
JavaScript
// JavaScript Code to Count Subarrays With Sum Divisible By K
// using Prefix Sum and Hash map

function subCount(arr, k) {
    let n = arr.length, res = 0;
    let prefCnt = 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 increment the result by 1
        // to count subarray arr[0...i]
        if (sum === 0)
            res += 1;

        // Add count of all starting points for index i
        res += (prefCnt.get(sum) || 0);

        prefCnt.set(sum, (prefCnt.get(sum) || 0) + 1);
    }

    return res;
}

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

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

Output
7

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




Next Article
Article Tags :

Similar Reads