Given an array arr[] consisting of N integers and a positive integer K, the task is to count the number of subarrays having exactly K elements occurring at least twice.
Examples:
Input: arr[] = {1, 1, 1, 2, 2}, K = 1
Output: 7
Explanation: The subarrays having exactly 1 element occurring at least twice are:
- {1, 1}. Frequency of 1 is 2.
- {1, 1, 1}. Frequency of 1 is 3.
- {1, 1, 1, 2}. Frequency of 1 is 3.
- {1, 1}. Frequency of 1 is 2.
- {1, 1, 2}. Frequency of 1 is 2.
- {1, 2, 2}. Frequency of 2 is 2.
- {2, 2}. Frequency of 2 is 2.
Therefore, the required output is 7.
Input: arr[] = {1, 2, 1, 2, 3}, K = 3
Output: 0
Naive Approach: The simplest approach to solve this problem is to generate all possible subarrays from the given array and count those subarrays having exactly K elements occurring at least twice. After having checked for all the subarrays, print the total number of subarrays obtained.
Time Complexity: O(N3)
Auxiliary Space: O(N)
Efficient Approach: The above approach can be optimized by using Hashing and Two pointers technique. Follow the steps below to solve the problem:
- Initialize a variable, say cntSub as 0, to store the count of all possible subarrays having exactly K elements occurring at least twice.
- Initialize two variables, say l as 0, and r as 0, to store the indices of the left and the right boundaries of each subarray respectively.
- Initialize a Map, say mp, and a Set, say S to store the count of elements in the subarrays and store the elements whose frequency in the subarray is at least 2 respectively.
- Iterate until r is less than N and perform the following operations:
- Iterate while r is less than N and the size of the set is at most K:
- Increment the count of arr[r] in mp and then push the element into set S if mp[arr[r]] is equal to 2.
- Increment r by 1.
- If the size of the set S is K then, increment the cntSub by 1.
- Iterate while l < r and the size of the set is greater than K:
- Decrement the count of arr[l] in mp and then erase the element from set S if mp[arr[r]] is equal to 1.
- Increment the cntSub and l by 1.
- Now iterate while l < N and the size of the set is K and decrement the count of arr[l] by 1 and if the frequency of arr[l] is 1, then erase the arr[l] from the set.
- After completing the above steps, print the value of cntSub as the resultant count of subarrays.
Below is the implementation of the above approach:
C++14
#include <bits/stdc++.h>
using namespace std;
int cntSubarrays( int A[], int K, int n)
{
int cntSub = 0;
map< int , int > mp;
int l = 0, r = 0;
set< int > st;
while (r < n) {
while (r < n && st.size() <= K) {
if (mp[A[r]]) {
st.insert(A[r]);
}
mp[A[r]]++;
r++;
if (st.size() == K)
cntSub++;
}
while (l < r && st.size() > K) {
cntSub++;
mp[A[l]]--;
if (mp[A[l]] == 1) {
st.erase(st.find(A[l]));
}
l++;
}
}
while (l < n && st.size() == K) {
cntSub++;
mp[A[l]]--;
if (mp[A[l]] == 1) {
st.erase(st.find(A[l]));
}
l++;
}
return cntSub;
}
int main()
{
int arr[] = { 1, 1, 1, 2, 2 };
int K = 1;
int N = sizeof (arr) / sizeof (arr[0]);
cout << cntSubarrays(arr, K, N);
return 0;
}
|
Java
import java.util.*;
class GFG {
static int cntSubarrays( int [] A, int K, int n)
{
int cntSub = 0 ;
HashMap<Integer, Integer> mp
= new HashMap<Integer, Integer>();
int l = 0 , r = 0 ;
HashSet<Integer> st = new HashSet<Integer>();
while (r < n) {
while (r < n && st.size() <= K) {
if (mp.containsKey(A[r])) {
st.add(A[r]);
}
if (mp.containsKey(A[r]))
mp.put(A[r], mp.get(A[r]) + 1 );
else
mp.put(A[r], 1 );
r++;
if (st.size() == K)
cntSub++;
}
while (l < r && st.size() > K) {
cntSub++;
if (mp.containsKey(A[l]))
mp.put(A[l], mp.get(A[l]) - 1 );
if (mp.get(A[l]) == 1 ) {
st.remove(A[l]);
}
l++;
}
}
while (l < n && st.size() == K) {
cntSub++;
if (mp.containsKey(A[l]))
mp.put(A[l], mp.get(A[l]) - 1 );
if (mp.get(A[l]) == 1 ) {
st.remove(A[l]);
}
l++;
}
return cntSub;
}
public static void main(String[] args)
{
int [] arr = { 1 , 1 , 1 , 2 , 2 };
int K = 1 ;
int N = arr.length;
System.out.println(cntSubarrays(arr, K, N));
}
}
|
Python3
def cntSubarrays(A, K, n):
cntSub = 0
mp = {}
l = 0
r = 0
st = set ()
while (r < n):
while (r < n and len (st) < = K):
if (A[r] in mp):
st.add(A[r])
if (A[r] in mp):
mp[A[r]] + = 1
else :
mp[A[r]] = 1
r + = 1
if ( len (st) = = K):
cntSub + = 1
while (l < r and len (st) > K):
cntSub + = 1
if (A[l] in mp):
mp[A[l]] - = 1
else :
mp[A[l]] = 1
if (mp[A[l]] = = 1 ):
st.remove(A[l])
l + = 1
while (l < n and len (st) = = K):
cntSub + = 1
mp[A[l]] - = 1
if (mp[A[l]] = = 1 ):
st.remove(A[l])
l + = 1
return cntSub
if __name__ = = '__main__' :
arr = [ 1 , 1 , 1 , 2 , 2 ]
K = 1
N = len (arr)
print (cntSubarrays(arr, K, N))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int cntSubarrays( int []A, int K, int n)
{
int cntSub = 0;
Dictionary< int , int > mp = new Dictionary< int , int >();
int l = 0, r = 0;
HashSet< int > st = new HashSet< int >();
while (r < n) {
while (r < n && st.Count <= K) {
if (mp.ContainsKey(A[r])) {
st.Add(A[r]);
}
if (mp.ContainsKey(A[r]))
mp[A[r]]++;
else
mp[A[r]] = 1;
r++;
if (st.Count == K)
cntSub++;
}
while (l < r && st.Count > K) {
cntSub++;
if (mp.ContainsKey(A[l]))
mp[A[l]]--;
if (mp[A[l]] == 1) {
st.Remove(A[l]);
}
l++;
}
}
while (l < n && st.Count == K) {
cntSub++;
if (mp.ContainsKey(A[l]))
mp[A[l]]--;
if (mp[A[l]] == 1) {
st.Remove(A[l]);
}
l++;
}
return cntSub;
}
public static void Main()
{
int []arr = { 1, 1, 1, 2, 2 };
int K = 1;
int N = arr.Length;
Console.WriteLine(cntSubarrays(arr, K, N));
}
}
|
Javascript
<script>
function cntSubarrays(A,K,n)
{
let cntSub = 0;
let mp = new Map();
let l = 0, r = 0;
let st = new Set();
while (r < n) {
while (r < n && st.size <= K) {
if (mp.has(A[r])) {
st.add(A[r]);
}
if (mp.has(A[r]))
mp.set(A[r], mp.get(A[r]) + 1);
else
mp.set(A[r], 1);
r++;
if (st.size == K)
cntSub++;
}
while (l < r && st.size > K) {
cntSub++;
if (mp.has(A[l]))
mp.set(A[l], mp.get(A[l]) - 1);
if (mp.get(A[l]) == 1) {
st. delete (A[l]);
}
l++;
}
}
while (l < n && st.size == K) {
cntSub++;
if (mp.has(A[l]))
mp.set(A[l], mp.get(A[l]) - 1);
if (mp.get(A[l]) == 1) {
st. delete (A[l]);
}
l++;
}
return cntSub;
}
let arr=[1, 1, 1, 2, 2 ];
let K = 1;
let N = arr.length;
document.write(cntSubarrays(arr, K, N));
</script>
|
Time Complexity: O(N*log N)
Auxiliary Space: O(N)