Count all sub-arrays having sum divisible by k
You are given an array of positive and/or negative integers and a value K . The task is to find count of all sub-arrays whose sum is divisible by K?
Examples :
Input : arr[] = {4, 5, 0, -2, -3, 1}, K = 5 Output : 7 // there are 7 sub-arrays whose sum is divisible by K // {4, 5, 0, -2, -3, 1} // {5} // {5, 0} // {5, 0, -2, -3} // {0} // {0, -2, -3} // {-2, -3}
A simple solution for this problem is to one by one calculate sum of all sub-arrays possible and check divisible by K. The time complexity for this approach will be O(n^2).
C++
#include <iostream> #include<bits/stdc++.h> using namespace std; int main() { vector< int >v{4, 5, 0, -2, -3, 1}; int k=5; int cnt=0; for ( int i=0;i<v.size();i++){ int sum=0; for ( int j=i;j<v.size();j++){ sum+=v[j]; if (sum%k==0)++cnt; } } cout<< "Count Of all sub-arrays having sum divisible by k :" <<endl; cout<<cnt<<endl; return 0; } |
Java
import java.util.*; class Main { public static void main(String[] args) { int [] v = { 4 , 5 , 0 , - 2 , - 3 , 1 }; int k = 5 ; int cnt = 0 ; for ( int i = 0 ; i < v.length; i++) { int sum = 0 ; for ( int j = i; j < v.length; j++) { sum += v[j]; if (sum % k == 0 ) ++cnt; } } System.out.println( "Count Of all sub-arrays having sum divisible by k : " ); System.out.println(cnt); } } |
Python3
# python code this approach v = [ 4 , 5 , 0 , - 2 , - 3 , 1 ] k = 5 # Initializing the counter variable cnt = 0 # Looping through all possible sub-arrays for i in range ( len (v)): sum = 0 for j in range (i, len (v)): sum + = v[j] if sum % k = = 0 : # incrementing the counter if the sub-array sum is divisible by k cnt + = 1 # Printing the count of all sub-arrays with sum divisible by k print ( "Count Of all sub-arrays having sum divisible by k:" ) print (cnt) |
C#
// C# program to find count of // subarrays with sum divisible by k. using System; class GFG { // Driver code public static void Main() { // array int [] arr = { 4, 5, 0, -2, -3, 1 }; // value of k int k = 5; // size of array int n = arr.Length; // variable to store answer int ans = 0; // iterating over array for ( int i = 0; i < n; i++) { int sum = 0; for ( int j = i; j < n; j++) { sum += arr[j]; if (sum % k == 0) ++ans; } } Console.WriteLine( "Count Of all sub-arrays having sum divisible by k :" ); Console.WriteLine(ans); } } // This code is contributed by shubhamrajput6156. |
Javascript
// Declare a vector of integers and initialize it let v = [4, 5, 0, -2, -3, 1]; // Set the value of k let k = 5; // Initialize a counter variable let cnt = 0; // Iterate over all possible sub-arrays of v for (let i = 0; i < v.length; i++) { let sum = 0; for (let j = i; j < v.length; j++) { // Calculate the sum of the current sub-array sum += v[j]; // Check if the sum is divisible by k if (sum % k === 0) { cnt++; } } } // Print the count of all sub-arrays having sum divisible by k console.log( "Count of all sub-arrays having sum divisible by k:" ); console.log(cnt); // This code is contributed by sarojmcy2e |
Complexity Analysis:
Time Complexity : O(n^2).
Space Complexity : O(1).
An efficient solution is based on below observation.
Let there be a subarray (i, j) whose sum is divisible by k sum(i, j) = sum(0, j) - sum(0, i-1) Sum for any subarray can be written as q*k + rem where q is a quotient and rem is remainder Thus, sum(i, j) = (q1 * k + rem1) - (q2 * k + rem2) sum(i, j) = (q1 - q2)k + rem1-rem2 We see, for sum(i, j) i.e. for sum of any subarray to be divisible by k, the RHS should also be divisible by k. (q1 - q2)k is obviously divisible by k, for (rem1-rem2) to follow the same, rem1 = rem2 where rem1 = Sum of subarray (0, j) % k rem2 = Sum of subarray (0, i-1) % k
So if any sub-array sum from index i’th to j’th is divisible by k then we can saya[0]+…a[i-1] (mod k) = a[0]+…+a[j] (mod k)
The above explanation is provided by Ekta Goel.
So we need to find such a pair of indices (i, j) that they satisfy the above condition.
Here is the algorithm :
- Make an auxiliary array of size k as Mod[k] . This array holds the count of each remainder we are getting after dividing cumulative sum till any index in arr[].
- Now start calculating cumulative sum and simultaneously take it’s mod with K, whichever remainder we get increment count by 1 for remainder as index in Mod[] auxiliary array. Sub-array by each pair of positions with same value of ( cumSum % k) constitute a continuous range whose sum is divisible by K.
- Now traverse Mod[] auxiliary array, for any Mod[i] > 1 we can choose any two pair of indices for sub-array by (Mod[i]*(Mod[i] – 1))/2 number of ways . Do the same for all remainders < k and sum up the result that will be the number all possible sub-arrays divisible by K.
Implementation:
C++
// C++ program to find count of subarrays with // sum divisible by k. #include <bits/stdc++.h> using namespace std; // Handles all the cases // function to find all sub-arrays divisible by k // modified to handle negative numbers as well int subCount( int arr[], int n, int k) { // create auxiliary hash array to count frequency // of remainders int mod[k]; memset (mod, 0, sizeof (mod)); // Traverse original array and compute cumulative // sum take remainder of this current cumulative // sum and increase count by 1 for this remainder // in mod[] array int cumSum = 0; for ( int i = 0; i < n; i++) { cumSum += arr[i]; // as the sum can be negative, taking modulo twice mod[((cumSum % k) + k) % k]++; } int result = 0; // Initialize result // Traverse mod[] for ( int i = 0; i < k; i++) // If there are more than one prefix subarrays // with a particular mod value. if (mod[i] > 1) result += (mod[i] * (mod[i] - 1)) / 2; // add the elements which are divisible by k itself // i.e., the elements whose sum = 0 result += mod[0]; return result; } // Driver program to run the case int main() { int arr[] = { 4, 5, 0, -2, -3, 1 }; int k = 5; int n = sizeof (arr) / sizeof (arr[0]); cout << subCount(arr, n, k) << endl; int arr1[] = { 4, 5, 0, -12, -23, 1 }; int k1 = 5; int n1 = sizeof (arr1) / sizeof (arr1[0]); cout << subCount(arr1, n1, k1) << endl; return 0; } // This code is corrected by Ashutosh Kumar |
Java
// Java program to find count of // subarrays with sum divisible by k. import java.util.*; class GFG { // Handles all the cases // function to find all sub-arrays divisible by k // modified to handle negative numbers as well static int subCount( int arr[], int n, int k) { // create auxiliary hash array to // count frequency of remainders int mod[] = new int [k]; Arrays.fill(mod, 0 ); // Traverse original array and compute cumulative // sum take remainder of this current cumulative // sum and increase count by 1 for this remainder // in mod[] array int cumSum = 0 ; for ( int i = 0 ; i < n; i++) { cumSum += arr[i]; // as the sum can be negative, taking modulo twice mod[((cumSum % k) + k) % k]++; } // Initialize result int result = 0 ; // Traverse mod[] for ( int i = 0 ; i < k; i++) // If there are more than one prefix subarrays // with a particular mod value. if (mod[i] > 1 ) result += (mod[i] * (mod[i] - 1 )) / 2 ; // add the elements which are divisible by k itself // i.e., the elements whose sum = 0 result += mod[ 0 ]; return result; } // Driver code public static void main(String[] args) { int arr[] = { 4 , 5 , 0 , - 2 , - 3 , 1 }; int k = 5 ; int n = arr.length; System.out.println(subCount(arr, n, k)); int arr1[] = { 4 , 5 , 0 , - 12 , - 23 , 1 }; int k1 = 5 ; int n1 = arr1.length; System.out.println(subCount(arr1, n1, k1)); } } // This code is contributed by Anant Agarwal. |
Python3
# Python program to find # count of subarrays with # sum divisible by k. # Handles all the cases # function to find all # sub-arrays divisible by k # modified to handle # negative numbers as well def subCount(arr, n, k): # create auxiliary hash # array to count frequency # of remainders mod = [] for i in range (k + 1 ): mod.append( 0 ) # Traverse original array # and compute cumulative # sum take remainder of this # current cumulative # sum and increase count by # 1 for this remainder # in mod[] array cumSum = 0 for i in range (n): cumSum = cumSum + arr[i] # as the sum can be negative, # taking modulo twice mod[((cumSum % k) + k) % k] = mod[((cumSum % k) + k) % k] + 1 result = 0 # Initialize result # Traverse mod[] for i in range (k): # If there are more than # one prefix subarrays # with a particular mod value. if (mod[i] > 1 ): result = result + (mod[i] * (mod[i] - 1 )) / / 2 # add the elements which # are divisible by k itself # i.e., the elements whose sum = 0 result = result + mod[ 0 ] return result # driver code arr = [ 4 , 5 , 0 , - 2 , - 3 , 1 ] k = 5 n = len (arr) print (subCount(arr, n, k)) arr1 = [ 4 , 5 , 0 , - 12 , - 23 , 1 ] k1 = 5 n1 = len (arr1) print (subCount(arr1, n1, k1)) # This code is contributed # by Anant Agarwal. |
C#
// C# program to find count of // subarrays with sum divisible by k. using System; class GFG { // Handles all the cases // function to find all sub-arrays divisible by k // modified to handle negative numbers as well static int subCount( int [] arr, int n, int k) { // create auxiliary hash array to // count frequency of remainders int [] mod = new int [k]; // Traverse original array and compute cumulative // sum take remainder of this current cumulative // sum and increase count by 1 for this remainder // in mod[] array int cumSum = 0; for ( int i = 0; i < n; i++) { cumSum += arr[i]; // as the sum can be negative, taking modulo twice mod[((cumSum % k) + k) % k]++; } // Initialize result int result = 0; // Traverse mod[] for ( int i = 0; i < k; i++) // If there are more than one prefix subarrays // with a particular mod value. if (mod[i] > 1) result += (mod[i] * (mod[i] - 1)) / 2; // add the elements which are divisible by k itself // i.e., the elements whose sum = 0 result += mod[0]; return result; } // Driver code public static void Main() { int [] arr = { 4, 5, 0, -2, -3, 1 }; int k = 5; int n = arr.Length; Console.WriteLine(subCount(arr, n, k)); int [] arr1 = { 4, 5, 0, -12, -23, 1 }; int k1 = 5; int n1 = arr1.Length; Console.WriteLine(subCount(arr1, n1, k1)); } } // This code is contributed by vt_m. |
Javascript
<script> // Javascript program to find count of // subarrays with sum divisible by k. // Handles all the cases // function to find all sub-arrays divisible by k // modified to handle negative numbers as well function subCount(arr, n, k) { // create auxiliary hash array to // count frequency of remainders let mod = new Array(k); mod.fill(0); // Traverse original array and compute cumulative // sum take remainder of this current cumulative // sum and increase count by 1 for this remainder // in mod[] array let cumSum = 0; for (let i = 0; i < n; i++) { cumSum += arr[i]; // as the sum can be negative, taking modulo twice mod[((cumSum % k) + k) % k]++; } // Initialize result let result = 0; // Traverse mod[] for (let i = 0; i < k; i++) // If there are more than one prefix subarrays // with a particular mod value. if (mod[i] > 1) result += parseInt((mod[i] * (mod[i] - 1)) / 2, 10); // add the elements which are divisible by k itself // i.e., the elements whose sum = 0 result += mod[0]; return result; } let arr = [ 4, 5, 0, -2, -3, 1 ]; let k = 5; let n = arr.length; document.write(subCount(arr, n, k) + "</br>" ); let arr1 = [ 4, 5, 0, -12, -23, 1 ]; let k1 = 5; let n1 = arr1.length; document.write(subCount(arr1, n1, k1)); </script> |
7 7
Time complexity : O(n + k)
Auxiliary Space : O(k)
This article is contributed by Shashank Mishra ( Gullu ). If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please Login to comment...