Count of subarrays with average K
Last Updated :
03 Aug, 2022
Given an array arr[] of size N, the task is to count the number of subarrays having an average exactly equal to k.
Examples:
Input: arr[ ] = {1, 4, 2, 6, 10}, N = 6, K = 4
Output: 3
Explanation: The subarrays with an average equal to 4 are {4}, {2, 6}, {4, 2, 6}.
Input: arr[ ] = {12, 5, 3, 10, 4, 8, 10, 12, -6, -1}, N = 10, K = 6
Output: 4
Naive Approach: The simplest approach to solve the problem is to traverse all the subarrays and calculate their average. If their average is K, then increase the answer.
Below is the implementation of the naive approach:
C++
#include <bits/stdc++.h>
using namespace std;
int countKAverageSubarrays( int arr[], int n, int k)
{
int res = 0;
for ( int L = 0; L < n; L++) {
int sum = 0;
for ( int R = L; R < n; R++) {
sum += arr[R];
int len = (R - L + 1);
if (sum % len == 0) {
int avg = sum / len;
if (avg == k)
res++;
}
}
}
return res;
}
int main()
{
int K = 6;
int arr[] = { 12, 5, 3, 10, 4, 8, 10, 12, -6, -1 };
int N = sizeof (arr) / sizeof (arr[0]);
cout << countKAverageSubarrays(arr, N, K);
}
|
Java
import java.io.*;
class GFG{
static int countKAverageSubarrays( int arr[], int n,
int k)
{
int res = 0 ;
for ( int L = 0 ; L < n; L++)
{
int sum = 0 ;
for ( int R = L; R < n; R++)
{
sum += arr[R];
int len = (R - L + 1 );
if (sum % len == 0 )
{
int avg = sum / len;
if (avg == k)
res++;
}
}
}
return res;
}
public static void main(String[] args)
{
int K = 6 ;
int arr[] = { 12 , 5 , 3 , 10 , 4 ,
8 , 10 , 12 , - 6 , - 1 };
int N = arr.length;
System.out.print(countKAverageSubarrays(arr, N, K));
}
}
|
Python3
def countKAverageSubarrays(arr, n, k):
res = 0
for L in range (n):
sum = 0
for R in range (L,n, 1 ):
sum + = arr[R]
len1 = (R - L + 1 )
if ( sum % len1 = = 0 ):
avg = sum / / len1
if (avg = = k):
res + = 1
return res
if __name__ = = '__main__' :
K = 6
arr = [ 12 , 5 , 3 , 10 , 4 , 8 , 10 , 12 , - 6 , - 1 ]
N = len (arr)
print (countKAverageSubarrays(arr, N, K))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int countKAverageSubarrays( int []arr, int n, int k)
{
int res = 0;
for ( int L = 0; L < n; L++)
{
int sum = 0;
for ( int R = L; R < n; R++)
{
sum += arr[R];
int len = (R - L + 1);
if (sum % len == 0) {
int avg = sum / len;
if (avg == k)
res++;
}
}
}
return res;
}
public static void Main()
{
int K = 6;
int []arr = { 12, 5, 3, 10, 4, 8, 10, 12, -6, -1 };
int N = arr.Length;
Console.Write(countKAverageSubarrays(arr, N, K));
}
}
|
Javascript
<script>
function countKAverageSubarrays(arr, n, k)
{
let res = 0;
for (let L = 0; L < n; L++)
{
let sum = 0;
for (let R = L; R < n; R++)
{
sum += arr[R];
let len = R - L + 1;
if (sum % len == 0)
{
let avg = sum / len;
if (avg == k)
res++;
}
}
}
return res;
}
let K = 6;
let arr = [12, 5, 3, 10, 4, 8, 10, 12, -6, -1];
let N = arr.length;
document.write(countKAverageSubarrays(arr, N, K));
</script>
|
Time Complexity: O(N^2)
Auxiliary Space: O(1)
Efficient Approach: An efficient solution is based on the observations below:
Let there be a subarray [L, R] whose average is equal to K, then
=> K = average[L, R] = sum[0, R] – sum[0, L-1] / (R – L + 1)
=> (R – L + 1) * K = sum[0, R] – sum[0, L – 1]
=> R * k – (L – 1)* K = sum[0, R] – sum[0, L – 1]
=> sum[0, R] – R * k = sum[0, L – 1] – (L – 1)* K
If every element is decreased by K, then the average will also decrease by K. Therefore, the average can be reduced to zero, so the problem becomes finding the number of subarrays having average equals zero.
The average zero is possible only if:
sum[0, R] – sum[0, L-1] / (R – L + 1) = 0
=> sum[0, R] = sum[0, L-1]
Follow the steps below to solve this problem :
- Initialize a map say, mp to store the frequency of prefix sum of the array arr[].
- Initialize a variable, say, curSum and result as 0.
- Iterate in the range[0, N-1] using the variable i:
- Subtract K from current element, then add it to curSum.
- If curSum is 0, subarray having an average equal to 0 is found, so increment the result by 1.
- If curSum has previously occurred before using a map. If it has occurred before then add the number of times it has occurred before to the result, then increase the frequency of curSum using the map.
- After completing the above steps, print the result as the answer.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int countKAverageSubarrays( int arr[], int n, int k)
{
int result = 0, curSum = 0;
unordered_map< int , int > mp;
for ( int i = 0; i < n; i++) {
curSum += (arr[i] - k);
if (curSum == 0)
result++;
if (mp.find(curSum) != mp.end())
result += mp[curSum];
mp[curSum]++;
}
return result;
}
int main()
{
int K = 6;
int arr[] = { 12, 5, 3, 10, 4, 8, 10, 12, -6, -1 };
int N = sizeof (arr) / sizeof (arr[0]);
cout << countKAverageSubarrays(arr, N, K);
}
|
Java
import java.util.*;
class GFG{
static int countKAverageSubarrays( int [] arr, int n,
int k)
{
int result = 1 , curSum = 0 ;
HashMap<Integer,
Integer> mp = new HashMap<Integer,
Integer>();
for ( int i = 0 ; i < n; i++)
{
curSum += (arr[i] - k);
if (curSum == 0 )
result++;
if (mp.containsKey(curSum))
result += mp.get(curSum);
if (mp.containsKey(curSum))
mp.put(curSum, mp.get(curSum) + 1 );
else
mp.put(curSum, 1 );
}
return result;
}
public static void main(String[] args)
{
int K = 6 ;
int [] arr = { 12 , 5 , 3 , 10 , 4 ,
8 , 10 , 12 , - 6 , - 1 };
int N = arr.length;
System.out.print(countKAverageSubarrays(arr, N, K));
}
}
|
Python3
def countKAverageSubarrays(arr, n, k):
result = 0
curSum = 0
mp = dict ()
for i in range ( 0 , n):
curSum + = (arr[i] - k)
if (curSum = = 0 ):
result + = 1
if curSum in mp:
result + = mp[curSum]
if curSum in mp:
mp[curSum] + = 1
else :
mp[curSum] = 1
return result
if __name__ = = '__main__' :
K = 6
arr = [ 12 , 5 , 3 , 10 , 4 , 8 , 10 , 12 , - 6 , - 1 ]
N = len (arr)
print (countKAverageSubarrays(arr, N, K))
|
C#
using System;
using System.Collections.Generic;
public class GFG{
static int countKAverageSubarrays( int [] arr, int n,
int k)
{
int result = 1, curSum = 0;
Dictionary< int ,
int > mp = new Dictionary< int ,
int >();
for ( int i = 0; i < n; i++)
{
curSum += (arr[i] - k);
if (curSum == 0)
result++;
if (mp.ContainsKey(curSum))
result += mp[curSum];
else
mp.Add(curSum, 1);
}
return result;
}
public static void Main(String[] args)
{
int K = 6;
int [] arr = { 12, 5, 3, 10, 4,
8, 10, 12, -6, -1 };
int N = arr.Length;
Console.Write(countKAverageSubarrays(arr, N, K));
}
}
|
Javascript
<script>
function countKAverageSubarrays(arr, n, k) {
let result = 0, curSum = 0;
let mp = new Map();
for (let i = 0; i < n; i++) {
curSum += (arr[i] - k);
if (curSum == 0) {
result++;
}
if (mp.has(curSum)) {
result += mp.get(curSum);
}
if (mp.has(curSum)) {
mp.set(curSum, mp.get(curSum) + 1);
}
else {
mp.set(curSum, 1);
}
}
return result;
}
let K = 6;
let arr = [12, 5, 3, 10, 4, 8, 10, 12, -6, -1];
let N = arr.length;
document.write(countKAverageSubarrays(arr, N, K));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...