Open In App

# Count subarrays having exactly K elements occurring at least twice

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, 1}. Frequency of 1 is 2.
2. {1, 1, 1}. Frequency of 1 is 3.
3. {1, 1, 1, 2}. Frequency of 1 is 3.
4. {1, 1}. Frequency of 1 is 2.
5. {1, 1, 2}. Frequency of 1 is 2.
6. {1, 2, 2}. Frequency of 2 is 2.
7. {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

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// Function to count the subarrays with``// exactly K elements occurring twice``int` `cntSubarrays(``int` `A[], ``int` `K, ``int` `n)``{``    ``// Stores the count of subarrays``    ``// having exactly K elements``    ``// occurring at least twice``    ``int` `cntSub = 0;` `    ``// Stores the count of``    ``// integers in the subarray``    ``map<``int``, ``int``> mp;` `    ``// Stores the indices of left``    ``// boundary and right boundary``    ``int` `l = 0, r = 0;` `    ``// Store the elements which occurs``    ``// atleast twice between [l, r]``    ``set<``int``> st;` `    ``// Iterate while r < n``    ``while` `(r < n) {` `        ``// Iterate while r < n``        ``// and size of st <= K``        ``while` `(r < n && st.size() <= K) {` `            ``// If mp[A[r]] >= 1``            ``if` `(mp[A[r]]) {``                ``st.insert(A[r]);``            ``}` `            ``// Increment count of A[r]``            ``mp[A[r]]++;` `            ``// Increment r by 1``            ``r++;` `            ``// If st.size() is K``            ``if` `(st.size() == K)``                ``cntSub++;``        ``}` `        ``// Iterate while l < r``        ``// and st.size() > K``        ``while` `(l < r && st.size() > K) {` `            ``// Increment cntSub by 1``            ``cntSub++;` `            ``// Decrement cntSub by 1``            ``mp[A[l]]--;` `            ``// If mp[A[l]] = 1``            ``if` `(mp[A[l]] == 1) {``                ``st.erase(st.find(A[l]));``            ``}` `            ``// Increment l by 1``            ``l++;``        ``}``    ``}` `    ``// Iterate while l < n  and``    ``// st.size() == K``    ``while` `(l < n && st.size() == K) {` `        ``// Increment cntSub by 1``        ``cntSub++;` `        ``mp[A[l]]--;` `        ``// If Mp[A[l]] is equal to 1``        ``if` `(mp[A[l]] == 1) {``            ``st.erase(st.find(A[l]));``        ``}` `        ``// Increment l by 1``        ``l++;``    ``}` `    ``// Return cntSub``    ``return` `cntSub;``}` `// Driver Code``int` `main()``{``    ``int` `arr[] = { 1, 1, 1, 2, 2 };``    ``int` `K = 1;``    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);` `    ``cout << cntSubarrays(arr, K, N);` `    ``return` `0;``}`

## Java

 `// Java program for the above approach``import` `java.util.*;``class` `GFG {` `  ``// Function to count the subarrays with``  ``// exactly K elements occurring twice``  ``static` `int` `cntSubarrays(``int``[] A, ``int` `K, ``int` `n)``  ``{` `    ``// Stores the count of subarrays``    ``// having exactly K elements``    ``// occurring at least twice``    ``int` `cntSub = ``0``;` `    ``// Stores the count of``    ``// integers in the subarray``    ``HashMap mp``      ``= ``new` `HashMap();` `    ``// Stores the indices of left``    ``// boundary and right boundary``    ``int` `l = ``0``, r = ``0``;` `    ``// Store the elements which occurs``    ``// atleast twice between [l, r]``    ``HashSet st = ``new` `HashSet();` `    ``// Iterate while r < n``    ``while` `(r < n) {` `      ``// Iterate while r < n``      ``// and size of st <= K``      ``while` `(r < n && st.size() <= K) {` `        ``// If mp[A[r]] >= 1``        ``if` `(mp.containsKey(A[r])) {``          ``st.add(A[r]);``        ``}` `        ``// Increment count of A[r]``        ``if` `(mp.containsKey(A[r]))``          ``mp.put(A[r], mp.get(A[r]) + ``1``);``        ``else``          ``mp.put(A[r], ``1``);` `        ``// Increment r by 1``        ``r++;` `        ``// If st.size() is K``        ``if` `(st.size() == K)``          ``cntSub++;``      ``}` `      ``// Iterate while l < r``      ``// and st.size() > K``      ``while` `(l < r && st.size() > K) {` `        ``// Increment cntSub by 1``        ``cntSub++;` `        ``// Decrement cntSub by 1``        ``if` `(mp.containsKey(A[l]))``          ``mp.put(A[l], mp.get(A[l]) - ``1``);` `        ``// If mp[A[l]] = 1``        ``if` `(mp.get(A[l]) == ``1``) {``          ``st.remove(A[l]);``        ``}` `        ``// Increment l by 1``        ``l++;``      ``}``    ``}` `    ``// Iterate while l < n  and``    ``// st.size() == K``    ``while` `(l < n && st.size() == K) {` `      ``// Increment cntSub by 1``      ``cntSub++;``      ``if` `(mp.containsKey(A[l]))``        ``mp.put(A[l], mp.get(A[l]) - ``1``);` `      ``// If Mp[A[l]] is equal to 1``      ``if` `(mp.get(A[l]) == ``1``) {``        ``st.remove(A[l]);``      ``}` `      ``// Increment l by 1``      ``l++;``    ``}` `    ``// Return cntSub``    ``return` `cntSub;``  ``}` `  ``// Driver Code``  ``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));``  ``}``}` `// This code is contributed by ukasp.`

## Python3

 `# Python3 program for the above approach` `# Function to count the subarrays with``# exactly K elements occurring twice``def` `cntSubarrays(A, K, n):``    ` `    ``# Stores the count of subarrays``    ``# having exactly K elements``    ``# occurring at least twice``    ``cntSub ``=` `0` `    ``# Stores the count of``    ``# integers in the subarray``    ``mp ``=` `{}` `    ``# Stores the indices of left``    ``# boundary and right boundary``    ``l ``=` `0``    ``r ``=` `0` `    ``# Store the elements which occurs``    ``# atleast twice between [l, r]``    ``st ``=` `set``()` `    ``# Iterate while r < n``    ``while` `(r < n):``        ` `        ``# Iterate while r < n``        ``# and size of st <= K``        ``while` `(r < n ``and` `len``(st) <``=` `K):``            ` `            ``# If mp[A[r]] >= 1``            ``if` `(A[r] ``in` `mp):``                ``st.add(A[r])` `            ``# Increment count of A[r]``            ``if` `(A[r] ``in` `mp):``                ``mp[A[r]] ``+``=` `1``            ``else``:``                ``mp[A[r]] ``=` `1` `            ``# Increment r by 1``            ``r ``+``=` `1` `            ``# If st.size() is K``            ``if` `(``len``(st) ``=``=` `K):``                ``cntSub ``+``=` `1` `        ``# Iterate while l < r``        ``# and st.size() > K``        ``while` `(l < r ``and` `len``(st) > K):``            ` `            ``# Increment cntSub by 1``            ``cntSub ``+``=` `1` `            ``# Decrement cntSub by 1``            ``if` `(A[l] ``in` `mp):``                ``mp[A[l]] ``-``=` `1``            ``else``:``                ``mp[A[l]] ``=` `1`` ` `            ``# If mp[A[l]] = 1``            ``if` `(mp[A[l]] ``=``=` `1``):``                ``st.remove(A[l])` `            ``# Increment l by 1``            ``l ``+``=` `1` `    ``# Iterate while l < n  and``    ``# st.size() == K``    ``while` `(l < n ``and` `len``(st) ``=``=` `K):``        ` `        ``# Increment cntSub by 1``        ``cntSub ``+``=` `1` `        ``mp[A[l]] ``-``=` `1` `        ``# If Mp[A[l]] is equal to 1``        ``if` `(mp[A[l]] ``=``=` `1``):``            ``st.remove(A[l])` `        ``# Increment l by 1``        ``l ``+``=` `1` `    ``# Return cntSub``    ``return` `cntSub` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``    ` `    ``arr ``=`  `[``1``, ``1``, ``1``, ``2``, ``2``]``    ``K ``=` `1``    ``N ``=` `len``(arr)``    ` `    ``print``(cntSubarrays(arr, K, N))` `# This code is contributed by ipg2016107`

## C#

 `// C# program for the above approach``using` `System;``using` `System.Collections.Generic;` `class` `GFG{` `  ``// Function to count the subarrays with``  ``// exactly K elements occurring twice``  ``static` `int` `cntSubarrays(``int` `[]A, ``int` `K, ``int` `n)``  ``{``    ` `    ``// Stores the count of subarrays``    ``// having exactly K elements``    ``// occurring at least twice``    ``int` `cntSub = 0;` `    ``// Stores the count of``    ``// integers in the subarray``    ``Dictionary<``int``,``int``> mp = ``new` `Dictionary<``int``,``int``>();` `    ``// Stores the indices of left``    ``// boundary and right boundary``    ``int` `l = 0, r = 0;` `    ``// Store the elements which occurs``    ``// atleast twice between [l, r]``    ``HashSet<``int``> st = ``new` `HashSet<``int``>();` `    ``// Iterate while r < n``    ``while` `(r < n) {` `      ``// Iterate while r < n``      ``// and size of st <= K``      ``while` `(r < n && st.Count <= K) {` `        ``// If mp[A[r]] >= 1``        ``if` `(mp.ContainsKey(A[r])) {``          ``st.Add(A[r]);``        ``}` `        ``// Increment count of A[r]``        ``if` `(mp.ContainsKey(A[r]))``          ``mp[A[r]]++;``        ``else``          ``mp[A[r]] = 1;` `        ``// Increment r by 1``        ``r++;` `        ``// If st.size() is K``        ``if` `(st.Count == K)``          ``cntSub++;``      ``}` `      ``// Iterate while l < r``      ``// and st.size() > K``      ``while` `(l < r && st.Count > K) {` `        ``// Increment cntSub by 1``        ``cntSub++;` `        ``// Decrement cntSub by 1``        ``if` `(mp.ContainsKey(A[l]))``          ``mp[A[l]]--;` `        ``// If mp[A[l]] = 1``        ``if` `(mp[A[l]] == 1) {``          ``st.Remove(A[l]);``        ``}` `        ``// Increment l by 1``        ``l++;``      ``}``    ``}` `    ``// Iterate while l < n  and``    ``// st.size() == K``    ``while` `(l < n && st.Count == K) {` `      ``// Increment cntSub by 1``      ``cntSub++;``      ``if` `(mp.ContainsKey(A[l]))``        ``mp[A[l]]--;` `      ``// If Mp[A[l]] is equal to 1``      ``if` `(mp[A[l]] == 1) {``        ``st.Remove(A[l]);``      ``}` `      ``// Increment l by 1``      ``l++;``    ``}` `    ``// Return cntSub``    ``return` `cntSub;``  ``}` `  ``// Driver Code``  ``public` `static` `void` `Main()``  ``{``    ``int` `[]arr = { 1, 1, 1, 2, 2 };``    ``int` `K = 1;``    ``int` `N = arr.Length;` `    ``Console.WriteLine(cntSubarrays(arr, K, N));``  ``}``}` `// This code is contributed by ipg2016107.`

## Javascript

 ``

Output:

`7`

Time Complexity: O(N*log N)
Auxiliary Space: O(N)