Count subarrays having sum modulo K same as the length of the subarray
Given an integer K and an array arr[] consisting of N positive integers, the task is to find the number of subarrays whose sum modulo K is equal to the size of the subarray.
Examples:
Input: arr[] = {1, 4, 3, 2}, K = 3
Output: 4
Explanation:
1 % 3 = 1
(1 + 4) % 3 = 2
4 % 3 = 1
(3 + 2) % 3 = 2
Therefore, subarrays {1}, {1, 4}, {4}, {3, 2} satisfy the required conditions.
Input: arr[] = {2, 3, 5, 3, 1, 5}, K = 4
Output: 5
Explanation:
The subarrays (5), (1), (5), (1, 5), (3, 5, 3) satisfy the required condition.
Naive Approach: The simplest approach is to find the prefix sum of the given array, then generate all the subarrays of the prefix sum array and count those subarrays having sum modulo K equal to the length of that subarray. Print the final count of subarrays obtained.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
long long int countSubarrays(
int a[], int n, int k)
{
int ans = 0;
vector< int > pref;
pref.push_back(0);
for ( int i = 0; i < n; i++)
pref.push_back((a[i]
+ pref[i])
% k);
for ( int i = 1; i <= n; i++) {
for ( int j = i; j <= n; j++) {
if ((pref[j] - pref[i - 1] + k) % k
== j - i + 1) {
ans++;
}
}
}
cout << ans << ' ' ;
}
int main()
{
int arr[] = { 2, 3, 5, 3, 1, 5 };
int N = sizeof (arr) / sizeof (arr[0]);
int K = 4;
countSubarrays(arr, N, K);
return 0;
}
|
Java
import java.util.*;
import java.lang.*;
import java.io.*;
class GFG{
static void countSubarrays( int a[], int n,
int k)
{
int ans = 0 ;
ArrayList<Integer> pref = new ArrayList<>();
pref.add( 0 );
for ( int i = 0 ; i < n; i++)
pref.add((a[i] + pref.get(i)) % k);
for ( int i = 1 ; i <= n; i++)
{
for ( int j = i; j <= n; j++)
{
if ((pref.get(j) -
pref.get(i - 1 ) + k) %
k == j - i + 1 )
{
ans++;
}
}
}
System.out.println(ans);
}
public static void main (String[] args)
throws java.lang.Exception
{
int arr[] = { 2 , 3 , 5 , 3 , 1 , 5 };
int N = arr.length;
int K = 4 ;
countSubarrays(arr, N, K);
}
}
|
Python3
def countSubarrays(a, n, k):
ans = 0
pref = []
pref.append( 0 )
for i in range (n):
pref.append((a[i] + pref[i]) % k)
for i in range ( 1 , n + 1 , 1 ):
for j in range (i, n + 1 , 1 ):
if ((pref[j] -
pref[i - 1 ] + k) %
k = = j - i + 1 ):
ans + = 1
print (ans, end = ' ' )
arr = [ 2 , 3 , 5 , 3 , 1 , 5 ]
N = len (arr)
K = 4
countSubarrays(arr, N, K)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static void countSubarrays( int [] a, int n,
int k)
{
int ans = 0;
List< int > pref = new List< int >();
pref.Add(0);
for ( int i = 0; i < n; i++)
pref.Add((a[i] + pref[i]) % k);
for ( int i = 1; i <= n; i++)
{
for ( int j = i; j <= n; j++)
{
if ((pref[j] -
pref[i - 1] + k) %
k == j - i + 1)
{
ans++;
}
}
}
Console.WriteLine(ans);
}
public static void Main ()
{
int [] arr = { 2, 3, 5, 3, 1, 5 };
int N = arr.Length;
int K = 4;
countSubarrays(arr, N, K);
}
}
|
Javascript
<script>
function countSubarrays( a, n, k)
{
var ans = 0;
var pref = [];
pref.push(0);
for ( var i = 0; i < n; i++)
pref.push((a[i]
+ pref[i])
% k);
for ( var i = 1; i <= n; i++) {
for ( var j = i; j <= n; j++) {
if ((pref[j] - pref[i - 1] + k) % k
== j - i + 1) {
ans++;
}
}
}
document.write( ans + ' ' );
}
var arr = [ 2, 3, 5, 3, 1, 5 ];
var N = arr.length;
var K = 4;
countSubarrays(arr, N, K);
</script>
|
Time Complexity: O(N2)
Auxiliary Space: O(N)
Efficient Approach: The idea is to generate the prefix sum of the given array and then the problem reduces to the count of subarray such that (pref[j] – pref[i]) % K equal to (j – i), where j > i and (j ? i) ? K. Below are the steps:
- Create an auxiliary array pref[] that stores the prefix sum of the given array.
- To count the subarray satisfying the above equation, the equation can be written as:
(pref[j] ? j) % k = (pref[i] ? i) % k, where j > i and (j ? i) ? K
- Traverse the prefix array pref[] and for each index j store the count (pref[j] – j) % K in a Map M.
- For each element pref[i] in the above steps update the count as M[(pref[i] – i % K + K) % K] and increment the frequency of (pref[i] – i % K + K) % K in the Map M.
- Print the value of the count of subarray after the above steps.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
long long int countSubarrays(
int a[], int n, int k)
{
unordered_map< int , int > cnt;
long long int ans = 0;
vector< int > pref;
pref.push_back(0);
for ( int i = 0; i < n; i++)
pref.push_back((a[i]
+ pref[i])
% k);
cnt[0] = 1;
for ( int i = 1; i <= n; i++) {
int remIdx = i - k;
if (remIdx >= 0) {
cnt[(pref[remIdx]
- remIdx % k + k)
% k]--;
}
ans += cnt[(pref[i]
- i % k + k)
% k];
cnt[(pref[i] - i % k + k) % k]++;
}
cout << ans << ' ' ;
}
int main()
{
int arr[] = { 2, 3, 5, 3, 1, 5 };
int N = sizeof (arr) / sizeof (arr[0]);
int K = 4;
countSubarrays(arr, N, K);
return 0;
}
|
Java
import java.util.*;
import java.lang.*;
import java.io.*;
class GFG{
static void countSubarrays( int a[], int n,
int k)
{
HashMap<Integer, Integer> cnt = new HashMap<>();
long ans = 0 ;
ArrayList<Integer> pref = new ArrayList<>();
pref.add( 0 );
for ( int i = 0 ; i < n; i++)
pref.add((a[i] + pref.get(i)) % k);
cnt.put( 0 , 1 );
for ( int i = 1 ; i <= n; i++)
{
int remIdx = i - k;
if (remIdx >= 0 )
{
if (cnt.containsKey((pref.get(remIdx) -
remIdx % k + k) % k))
cnt.put((pref.get(remIdx) -
remIdx % k + k) % k,
cnt.get((pref.get(remIdx) -
remIdx % k + k) % k) - 1 );
else
cnt.put((pref.get(remIdx) -
remIdx % k + k) % k, - 1 );
}
if (cnt.containsKey((pref.get(i) -
i % k + k) % k))
ans += cnt.get((pref.get(i) -
i % k + k) % k);
if (cnt.containsKey((pref.get(i) -
i % k + k) % k))
cnt.put((pref.get(i) -
i % k + k) % k,
cnt.get((pref.get(i) -
i % k + k) % k) + 1 );
else
cnt.put((pref.get(i) -
i % k + k) % k, 1 );
}
System.out.println(ans);
}
public static void main (String[] args)
throws java.lang.Exception
{
int arr[] = { 2 , 3 , 5 , 3 , 1 , 5 };
int N = arr.length;
int K = 4 ;
countSubarrays(arr, N, K);
}
}
|
Python3
def countSubarrays(a, n, k):
cnt = {}
ans = 0
pref = []
pref.append( 0 )
for i in range (n):
pref.append((a[i] + pref[i]) % k)
cnt[ 0 ] = 1
for i in range ( 1 , n + 1 ):
remIdx = i - k
if (remIdx > = 0 ):
if ((pref[remIdx] -
remIdx % k + k) % k in cnt):
cnt[(pref[remIdx] -
remIdx % k + k) % k] - = 1
else :
cnt[(pref[remIdx] -
remIdx % k + k) % k] = - 1
if (pref[i] - i % k + k) % k in cnt:
ans + = cnt[(pref[i] - i % k + k) % k]
if (pref[i] - i % k + k) % k in cnt:
cnt[(pref[i] - i % k + k) % k] + = 1
else :
cnt[(pref[i] - i % k + k) % k] = 1
print (ans, end = ' ' )
arr = [ 2 , 3 , 5 , 3 , 1 , 5 ]
N = len (arr)
K = 4
countSubarrays(arr, N, K)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static void countSubarrays( int []a, int n,
int k)
{
Dictionary< int ,
int > cnt = new Dictionary< int ,
int >();
long ans = 0;
List< int > pref = new List< int >();
pref.Add(0);
for ( int i = 0; i < n; i++)
pref.Add((a[i] + pref[i]) % k);
cnt.Add(0, 1);
for ( int i = 1; i <= n; i++)
{
int remIdx = i - k;
if (remIdx >= 0)
{
if (cnt.ContainsKey((pref[remIdx] -
remIdx % k + k) % k))
cnt[(pref[remIdx] -
remIdx % k + k) % k] = cnt[(pref[remIdx] -
remIdx % k + k) % k] - 1;
else
cnt.Add((pref[remIdx] -
remIdx % k + k) % k, -1);
}
if (cnt.ContainsKey((pref[i] -
i % k + k) % k))
ans += cnt[(pref[i] -
i % k + k) % k];
if (cnt.ContainsKey((pref[i] -
i % k + k) % k))
cnt[(pref[i] -
i % k + k) % k] = cnt[(pref[i] -
i % k + k) % k] + 1;
else
cnt.Add((pref[i] -
i % k + k) % k, 1);
}
Console.WriteLine(ans);
}
public static void Main(String[] args)
{
int []arr = {2, 3, 5, 3, 1, 5};
int N = arr.Length;
int K = 4;
countSubarrays(arr, N, K);
}
}
|
Javascript
<script>
function countSubarrays(a , n , k) {
var cnt = new Map();
var ans = 0;
var pref = [];
pref.push(0);
for (i = 0; i < n; i++)
pref.push((a[i] + pref[i]) % k);
cnt.set(0, 1);
for (i = 1; i <= n; i++) {
var remIdx = i - k;
if (remIdx >= 0) {
if (cnt.has((pref[remIdx] - remIdx % k + k) % k))
cnt.set((pref[remIdx] - remIdx % k + k) % k,
cnt.get((pref[remIdx] - remIdx % k + k) % k) - 1);
else
cnt.set((pref.get(remIdx) - remIdx % k + k) % k, -1);
}
if (cnt.has((pref[i] - i % k + k) % k))
ans += cnt.get((pref[i] - i % k + k) % k);
if (cnt.has((pref[i] - i % k + k) % k))
cnt.set((pref[i] - i % k + k) % k, cnt.get((pref[i] - i % k + k) % k) + 1);
else
cnt.set((pref[i] - i % k + k) % k, 1);
}
document.write(ans);
}
var arr = [ 2, 3, 5, 3, 1, 5 ];
var N = arr.length;
var K = 4;
countSubarrays(arr, N, K);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Last Updated :
03 May, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...