Count distinct elements in every window of size k

28 Jun, 2022
Given an array of size n and an integer k, return the count of distinct numbers in all windows of size k. 
Example: 
Input: arr[] = {1, 2, 1, 3, 4, 2, 3};
       k = 4
Output: 3 4 4 3

Explanation:
First window is {1, 2, 1, 3}, count of distinct numbers is 3
Second window is {2, 1, 3, 4} count of distinct numbers is 4
Third window is {1, 3, 4, 2} count of distinct numbers is 4
Fourth window is {3, 4, 2, 3} count of distinct numbers is 3

Input: arr[] = {1, 2, 4, 4};
       k = 2
Output: 2 2 1

Explanation:
First window is {1, 2}, count of distinct numbers is 2
First window is {2, 4}, count of distinct numbers is 2
First window is {4, 4}, count of distinct numbers is 1
 
Source: This problem has appeared in Microsoft Interview Question.Naive Approach: The naive solution is to traverse the given array considering every window in it and keeping a count on the distinct elements of the window. 
Algorithm: 
For every index i from 0 to len_array(n) – k, i.e n – k, traverse the array from i to i + k. This is the windowTraverse the window, from i to that index and check if the element is present or not.If the element is not present in the prefix of the array, i.e no duplicate element is present from i to index-1, then increase the count.Print the count.
For every index i from 0 to len_array(n) – k, i.e n – k, traverse the array from i to i + k. This is the window
Traverse the window, from i to that index and check if the element is present or not.
If the element is not present in the prefix of the array, i.e no duplicate element is present from i to index-1, then increase the count.
Print the count.
Below is the implementation of the above approach:
Chapters
descriptions off, selected
captions settings, opens captions settings dialog
captions off, selected
English
This is a modal window.
Beginning of dialog window. Escape will cancel and close the window.
End of dialog window.
C++
Java
Python3
C#
Javascript
// Simple C++ program to count distinct// elements in every window of size k#include <bits/stdc++.h>using namespace std; // Counts distinct elements in window of size kint countWindowDistinct(int win[], int k){    int dist_count = 0;     // Traverse the window    for (int i = 0; i < k; i++) {        // Check if element arr[i] exists in arr[0..i-1]        int j;        for (j = 0; j < i; j++)            if (win[i] == win[j])                break;        if (j == i)            dist_count++;    }    return dist_count;} // Counts distinct elements in all windows of size kvoid countDistinct(int arr[], int n, int k){    // Traverse through every window    for (int i = 0; i <= n - k; i++)        cout << countWindowDistinct(arr + i, k) << endl;} // Driver programint main(){    int arr[] = { 1, 2, 1, 3, 4, 2, 3 }, k = 4;    int n = sizeof(arr) / sizeof(arr[0]);    countDistinct(arr, n, k);    return 0;}
// Simple Java program to count distinct elements in every// window of size k import java.util.Arrays; class Test {    // Counts distinct elements in window of size k    static int countWindowDistinct(int win[], int k)    {        int dist_count = 0;         // Traverse the window        for (int i = 0; i < k; i++) {            // Check if element arr[i] exists in arr[0..i-1]            int j;            for (j = 0; j < i; j++)                if (win[i] == win[j])                    break;            if (j == i)                dist_count++;        }        return dist_count;    }     // Counts distinct elements in all windows of size k    static void countDistinct(int arr[], int n, int k)    {        // Traverse through every window        for (int i = 0; i <= n - k; i++)            System.out.println(countWindowDistinct(Arrays.copyOfRange(arr, i, arr.length), k));    }     // Driver method    public static void main(String args[])    {        int arr[] = { 1, 2, 1, 3, 4, 2, 3 }, k = 4;         countDistinct(arr, arr.length, k);    }}
# Simple Python3 program to count distinct# elements in every window of size kimport math as mt # Counts distinct elements in window# of size kdef countWindowDistinct(win, k):     dist_count = 0     # Traverse the window    for i in range(k):                 # Check if element arr[i] exists        # in arr[0..i-1]        j = 0        while j < i:            if (win[i] == win[j]):                break            else:                j += 1        if (j == i):            dist_count += 1         return dist_count  # Counts distinct elements in all# windows of size kdef countDistinct(arr, n, k):     # Traverse through every window    for i in range(n - k + 1):        print(countWindowDistinct(arr[i:k + i], k)) # Driver Codearr = [1, 2, 1, 3, 4, 2, 3]k = 4n = len(arr)countDistinct(arr, n, k) # This code is contributed by# Mohit kumar 29
// Simple C# program to count distinct// elements in every window of size kusing System;using System.Collections.Generic; class GFG {    // Counts distinct elements in    // window of size k    static int countWindowDistinct(int[] win,                                   int k)    {        int dist_count = 0;         // Traverse the window        for (int i = 0; i < k; i++) {            // Check if element arr[i]            // exists in arr[0..i-1]            int j;            for (j = 0; j < i; j++)                if (win[i] == win[j])                    break;            if (j == i)                dist_count++;        }        return dist_count;    }     // Counts distinct elements in    // all windows of size k    static void countDistinct(int[] arr,                              int n, int k)    {        // Traverse through every window        for (int i = 0; i <= n - k; i++) {            int[] newArr = new int[k];            Array.Copy(arr, i, newArr, 0, k);            Console.WriteLine(countWindowDistinct(newArr, k));        }    }     // Driver Code    public static void Main(String[] args)    {        int[] arr = { 1, 2, 1, 3, 4, 2, 3 };        int k = 4;         countDistinct(arr, arr.Length, k);    }} // This code is contributed by Princi Singh
<script> // Javascript program to count distinct elements in every// window of size k // Counts distinct elements in window of size k    function countWindowDistinct(win, k)    {        let dist_count = 0;          // Traverse the window        for (let i = 0; i < k; i++) {            // Check if element arr[i] exists in arr[0..i-1]            let j;            for (j = 0; j < i; j++)                if (win[i] == win[j])                    break;            if (j == i)                dist_count++;        }        return dist_count;    }      // Counts distinct elements in all windows of size k    function countDistinct(arr, n, k)    {        // Traverse through every window        for (let i = 0; i <= n - k; i++)            document.write(countWindowDistinct(arr.slice(i, arr.length), k) + "<br/>");    }  // Driver program       let arr = [ 1, 2, 1, 3, 4, 2, 3 ], k = 4;          countDistinct(arr, arr.length, k);   // This code is contributed by target_2.</script>
3
4
4
3
Complexity Analysis: 
Time complexity: O(nk2). The time complexity can be improved to O(n*k*log k) by modifying countWindowDistinct() by the use of sorting. The function can further be optimized to use hashing to find distinct elements in a window. With hashing the time complexity becomes O(n*k).
Space Complexity: O(1) No extra space is needed.
Efficient Approach: So, there is an efficient solution using hashing, though hashing requires extra O(n) space but the time complexity will improve. The trick is to use the count of the previous window while sliding the window. To do this a hash map can be used that stores elements of the current window. The hash-map is also operated on by simultaneous addition and removal of an element while keeping track of distinct elements. The problem deals with finding the count of distinct elements in a window of length k, at any step while shifting the window and discarding all the computation done in the previous step, even though k – 1 elements are same from the previous adjacent window. For example, assume that elements from index i to i + k – 1 are stored in a Hash Map as an element-frequency pair. So, while updating the Hash Map in range i + 1 to i + k, reduce the frequency of the i-th element by 1 and increase the frequency of (i + k)-th element by 1. Insertion and deletion from the HashMap takes constant time.
Algorithm: Create an empty hash map. Let the hash map be hM.Initialize the count of distinct elements as dist_count to 0.Traverse through the first window and insert elements of the first window to hM. The elements are used as key and their counts as the value in hM. Also, keep updating dist_countPrint distinct count for the first window.Traverse through the remaining array (or other windows).Remove the first element of the previous window. If the removed element appeared only once, remove it from hM and decrease the distinct count, i.e. do “dist_count–“else (appeared multiple times in hM), then decrement its count in hMAdd the current element (last element of the new window) If the added element is not present in hM, add it to hM and increase the distinct count, i.e. do “dist_count++”Else (the added element appeared multiple times), increment its count in hM
Create an empty hash map. Let the hash map be hM.Initialize the count of distinct elements as dist_count to 0.Traverse through the first window and insert elements of the first window to hM. The elements are used as key and their counts as the value in hM. Also, keep updating dist_countPrint distinct count for the first window.Traverse through the remaining array (or other windows).Remove the first element of the previous window. If the removed element appeared only once, remove it from hM and decrease the distinct count, i.e. do “dist_count–“else (appeared multiple times in hM), then decrement its count in hMAdd the current element (last element of the new window) If the added element is not present in hM, add it to hM and increase the distinct count, i.e. do “dist_count++”Else (the added element appeared multiple times), increment its count in hM
Create an empty hash map. Let the hash map be hM.
Initialize the count of distinct elements as dist_count to 0.
Traverse through the first window and insert elements of the first window to hM. The elements are used as key and their counts as the value in hM. Also, keep updating dist_count
Print distinct count for the first window.
Traverse through the remaining array (or other windows).
Remove the first element of the previous window. If the removed element appeared only once, remove it from hM and decrease the distinct count, i.e. do “dist_count–“else (appeared multiple times in hM), then decrement its count in hM
If the removed element appeared only once, remove it from hM and decrease the distinct count, i.e. do “dist_count–“
else (appeared multiple times in hM), then decrement its count in hM
Add the current element (last element of the new window) If the added element is not present in hM, add it to hM and increase the distinct count, i.e. do “dist_count++”Else (the added element appeared multiple times), increment its count in hM
If the added element is not present in hM, add it to hM and increase the distinct count, i.e. do “dist_count++”
Else (the added element appeared multiple times), increment its count in hM
Below is a dry run of the above approach:
Implementation:
C++
Java
Python3
C#
Javascript
// An efficient C++ program to// count distinct elements in// every window of size k#include <iostream>#include <unordered_map>using namespace std; void countDistinct(int arr[], int k, int n){    // Creates an empty hashmap hm    unordered_map<int, int> hm;     // initialize distinct element count for current window    int dist_count = 0;     // Traverse the first window and store count    // of every element in hash map    for (int i = 0; i < k; i++) {        if (hm[arr[i]] == 0) {            dist_count++;        }        hm[arr[i]] += 1;    }     // Print count of first window    cout << dist_count << endl;     // Traverse through the remaining array    for (int i = k; i < n; i++) {        // Remove first element of previous window        // If there was only one occurrence, then reduce distinct count.        if (hm[arr[i - k]] == 1) {            dist_count--;        }        // reduce count of the removed element        hm[arr[i - k]] -= 1;         // Add new element of current window        // If this element appears first time,        // increment distinct element count         if (hm[arr[i]] == 0) {            dist_count++;        }        hm[arr[i]] += 1;         // Print count of current window        cout << dist_count << endl;    }} int main(){    int arr[] = { 1, 2, 1, 3, 4, 2, 3 };    int size = sizeof(arr) / sizeof(arr[0]);    int k = 4;    countDistinct(arr, k, size);     return 0;}// This solution is contributed by Aditya Goel
// An efficient Java program to count distinct elements in// every window of size kimport java.util.HashMap; class CountDistinctWindow {    static void countDistinct(int arr[], int k)    {        // Creates an empty hashMap hM        HashMap<Integer, Integer> hM = new HashMap<Integer, Integer>();         // Traverse the first window and store count        // of every element in hash map        for (int i = 0; i < k; i++)            hM.put(arr[i], hM.getOrDefault(arr[i], 0) + 1);         // Print count of first window        System.out.println(hM.size());         // Traverse through the remaining array        for (int i = k; i < arr.length; i++) {             // Remove first element of previous window            // If there was only one occurrence            if (hM.get(arr[i - k]) == 1) {                hM.remove(arr[i - k]);            }             else // reduce count of the removed element                hM.put(arr[i - k],  hM.get(arr[i - k]) - 1);                        // Add new element of current window            // If this element appears first time,            // set its count as 1,            hM.put(arr[i], hM.getOrDefault(arr[i], 0) + 1);             // Print count of current window            System.out.println(hM.size());        }    }     // Driver method    public static void main(String arg[])    {        int arr[] = { 1, 2, 1, 3, 4, 2, 3 };        int k = 4;        countDistinct(arr, k);    }}
# An efficient Python program to# count distinct elements in# every window of size kfrom collections import defaultdict def countDistinct(arr, k, n):     # Creates an empty hashmap hm    mp = defaultdict(lambda:0)     # initialize distinct element    # count for current window    dist_count = 0     # Traverse the first window and store count    # of every element in hash map    for i in range(k):        if mp[arr[i]] == 0:            dist_count += 1        mp[arr[i]] += 1     # Print count of first window    print(dist_count)         # Traverse through the remaining array    for i in range(k, n):         # Remove first element of previous window        # If there was only one occurrence,        # then reduce distinct count.        if mp[arr[i - k]] == 1:            dist_count -= 1        mp[arr[i - k]] -= 1         # Add new element of current window    # If this element appears first time,    # increment distinct element count        if mp[arr[i]] == 0:            dist_count += 1        mp[arr[i]] += 1         # Print count of current window        print(dist_count) arr = [1, 2, 1, 3, 4, 2, 3]n = len(arr)k = 4countDistinct(arr, k, n) # This code is contributed by Shrikant13
// An efficient C# program to count// distinct elements in every window of size kusing System;using System.Collections.Generic; public class CountDistinctWindow {    static void countDistinct(int[] arr, int k)    {        // Creates an empty hashMap hM        Dictionary<int, int> hM = new Dictionary<int, int>();         // initialize distinct element count for        // current window        int dist_count = 0;         // Traverse the first window and store count        // of every element in hash map        for (int i = 0; i < k; i++) {            if (!hM.ContainsKey(arr[i])) {                hM.Add(arr[i], 1);                dist_count++;            }            else {                int count = hM[arr[i]];                hM.Remove(arr[i]);                hM.Add(arr[i], count + 1);            }        }         // Print count of first window        Console.WriteLine(dist_count);         // Traverse through the remaining array        for (int i = k; i < arr.Length; i++) {             // Remove first element of previous window            // If there was only one occurrence, then            // reduce distinct count.            if (hM[arr[i - k]] == 1) {                hM.Remove(arr[i - k]);                dist_count--;            }            else // reduce count of the removed element            {                int count = hM[arr[i - k]];                hM.Remove(arr[i - k]);                hM.Add(arr[i - k], count - 1);            }             // Add new element of current window            // If this element appears first time,            // increment distinct element count            if (!hM.ContainsKey(arr[i])) {                hM.Add(arr[i], 1);                dist_count++;            }            else // Increment distinct element count            {                int count = hM[arr[i]];                hM.Remove(arr[i]);                hM.Add(arr[i], count + 1);            }             // Print count of current window            Console.WriteLine(dist_count);        }    }     // Driver method    public static void Main(String[] arg)    {        int[] arr = { 1, 2, 1, 3, 4, 2, 3 };        int k = 4;        countDistinct(arr, k);    }} // This code contributed by Rajput-Ji
<script> // Javascript program to count distinct elements in// every window of size k        function countDistinct(arr, k)    {        // Creates an empty hashMap hM        let hM = new Map();         // Traverse the first window and store count        // of every element in hash map        for (let i = 0; i < k; i++)        {            if(hM.has(arr[i]))            hM.set(arr[i], hM.get(arr[i])+1)            else            hM.set(arr[i], 1);        }         // Print count of first window        document.write(hM.size + "<br/>");         // Traverse through the remaining array        for (let i = k; i < arr.length; i++) {             // Remove first element of previous window            // If there was only one occurrence            if (hM.get(arr[i - k]) == 1) {                hM.delete(arr[i - k]);            }             else // reduce count of the removed element                hM.set(arr[i - k],  hM.get(arr[i - k]) - 1);                        // Add new element of current window            // If this element appears first time,            // set its count as 1,            if(hM.has(arr[i]))            hM.set(arr[i], hM.get(arr[i])+1)            else            hM.set(arr[i], 1);             // Print count of current window            document.write(hM.size + "<br/>");        }    }  // Driver code    let arr = [ 1, 2, 1, 3, 4, 2, 3 ];    let size = arr.length;    let k = 4;    countDistinct(arr, k, size);         // This code is contributed by splevel62.</script>
3
4
4
3
Complexity Analysis: Time complexity O(n). A single traversal of the array is required.Space Complexity O(n). Since the hashmap requires linear space.
Time complexity O(n). A single traversal of the array is required.
Space Complexity O(n). Since the hashmap requires linear space.
This article is contributed by Piyush. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
mohit kumar 29
shrikanth13
Rajput-Ji
princi singh
andrew1234
harshga32
target_2
simranarora5sos
aryankadiya
splevel62
arorakashish0911
hardikkoriintern
Accolite
Amazon
Microsoft
sliding-window
Arrays
Hash
Accolite
Amazon
Microsoft
sliding-window
Arrays
Hash
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Maximum and minimum of an array using minimum number of comparisons
Top 50 Array Coding Problems for Interviews
Multidimensional Arrays in Java
Stack Data Structure (Introduction and Program)
Linear Search
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
What is Hashing | A Complete Tutorial
Hashing | Set 1 (Introduction)
Internal Working of HashMap in Java
Count pairs with given sum