Given an integer array arr[] and an integer K (greater than 0), the task is to count the subarray whose elements sum up to a multiple of K, else print -1. A number x is a multiple of K if there exists an integer y such that x = y*k. Remember 0 is also a multiple of K.
Examples:
Input: arr[] = {4,2,7,6}, K = 6 Output: 2 Explanation: There are 2 subarray whose sum of the elements is a multiple of k: {4,2} , {6} Input: arr[] = {0,0,1,-7,3}, K = 6 Output: 6 Explanation: The 3 subarrays whose sum is a multiple of 6 are: {0}, {0}, {0,0}, {1,-7}, {0,1,-7}, {0,0,1,-7} Input: {0,1,2,0}, K = 2 Output: 1 Explanation: The required subarray sum multiple of k : {0}, {0}, {2,0}, {2}
Approach:
The question is quite similar to subarray sum divisible by k. Here is the algorithm:
- Create a variable cursum, to store the sum till the current index and count to store the count of subarrays sum multiple of K. Initialize cursum and count as 0.
- Create an unordered_map mp to store key value as remainder of the cursum%K and mapped value as the count of it. Initialize mp[0] = 1,for the case when al the elements sum upto a multiple of K.
- Run a loop from index 0 to n(array size) and do the following steps inside it:
- Cursum+=arr[index]
- Create a variable rem = sum%k, this variable store remainder attained till the current index.
- Find in the map mp if there is a subarray with same remainder as rem, it means that there exist a subarray between them with sum multiple of K and update count, count+=mp[rem].
- update rem in the map mp.
4. Return the count.
Below is the C++ implementation of the above algorithm:
// C++ program to find the count of subarrays with // sum multiple of k. #include <bits/stdc++.h> using namespace std; // Function to find count of all sub-arrays divisible by K // modified to handle negative numbers as well int subarrayMultipleK(int arr[], int n, int K) { //Create an unordered map to store the remainder unordered_map<int,int>mp; //When whole subarray is multiple of K mp[0] = 1; //Varaible to store sum till current index int cursum = 0; //Variable to store the count of subarray //having sum multiple of K int count = 0; //Traverse the array and find the subarray //sum multiple of K for(int i=0;i<n;i++) { //Update cursum cursum+=arr[i]; int rem = cursum%K; //handle negative remainders if(rem < 0) { rem += K; } //Find if there a subarray with remainder //as rem in map, if present then //the subarray between it is a multiple //of K, update the count if(mp.find(rem)!=mp.end()) { count += mp[rem]; } //Increment rem in the map mp[rem]++; } //Return the count return count; } // Driver program to run the case int main() { int arr[] = { 4, 2, 7, 6}; int K = 6; int n = sizeof(arr) / sizeof(arr[0]); cout <<"Count of subarray multiple of "<<K<<": "<<subarrayMultipleK(arr, n, K) << endl; int arr1[] = { 0, 0, 1, -7, 3}; K = 6; n = sizeof(arr1) / sizeof(arr1[0]); cout<<"Count of subarray multiple of "<<K<<": "<<subarrayMultipleK(arr1, n, K) << endl; int arr2[] = {0, 1, 2, 0}; K = 2; n = sizeof(arr2) / sizeof(arr2[0]); cout<<"Count of subarray multiple of "<<K<<": "<<subarrayMultipleK(arr2,n,K)<< endl; return 0; }
Output:
Count of subarray multiple of 6: 2 Count of subarray multiple of 6: 6 Count of subarray multiple of 2: 4
Time Complexity: O(n)
Space Complexity: O(n)