algorithmalgorithmic-tradingarray-algorithms

Count distinct elements in every window using hash map


Given an array A[] of size N and an integer K. Your task is to complete the function countDistinct() which prints the count of distinct numbers in all windows of size k in the array A[].

Constraints:
1 <= T <= 100
1 <= N <= K <= 105
1 <= A[i] <= 105 , for each valid i

Input:
The first line of input contains an integer T denoting the number of test cases. Then T test cases follow. Each test case contains two integers N and K. Then in the next line are N space separated values of the array A[].

Output:
For each test case in a new line print the space separated values denoting counts of distinct numbers in all windows of size k in the array A[].

Example(To be used only for expected output):
Input:
2
7 4
1 2 1 3 4 2 3
3 2
4 1 1

Output:
3 4 4 3
2 1

Solution:

void countDistinct(int A[], int k, int n) {
    map<int, int> hash;
    int cnt=0;
    for(int i=0;i<n;i++) {
        if(i<k){
        hash[A[i]]++;
        }
        if(i==k-1) {
            cout<<hash.size()<<" ";
        }
        if(i>=k){
            if(hash[A[i-k]]==1){
            hash.erase(A[i-k]);
            } else {
                hash[A[i-k]]--;
            }
            hash[A[i]]++;
            cout<<hash.size()<<" ";
        }
    }    
}

where A[] is the array, n is the siz of array, k is the size of window. Algorithm: 1. Used a hash map to store count of elements until i==k. 2. When i==k, either decrement or erase A[i-k] count in the map; also increse count of A[i]. 3. Print the hashmap size for the no of distinct counts in the window k.

Algorithm which i have used is O(n), but geeksforgeeks give Time Limit Exceeded error. Am i going wrong anywhere ?


Solution

  • It's probably due to the use of map, as in map insertion and searching takes O(log N) time whereas in unordered_map, these operation take O(1) time in average. Also I think N and K are close to 10^5 in all the test cases, so by using map it takes O(T * N * O(log K)) making the time complexity in the range of O(100 * 100000 * 17) i.e O(1.7*10^8).

    Therefore use unordered_map as follows:

    void countDistinct(int A[], int k, int n) {
        unordered_map<int, int> hash;
        int cnt=0;
        for(int i=0;i<n;i++) {
            if(i<k){
                hash[A[i]]++;
            }
            if(i==k-1) {
                cout<<hash.size()<<" ";
            }
            if(i>=k){
                if(hash[A[i-k]]==1){
                    hash.erase(A[i-k]);
                } else {
                    hash[A[i-k]]--;
                }
                hash[A[i]]++;
                cout<<hash.size()<<" ";
            }
        }
    }
    

    Geeks For Geeks Verdict

    enter image description here