Open In App

Smallest subarray with k distinct numbers

Last Updated : 22 Jul, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

We are given an array consisting of n integers and an integer k. We need to find the minimum range in array [l, r] (both l and r are inclusive) such that there are exactly k different numbers. If such subarray doesn’t exist print “Invalid k”.
Examples: 

Input : arr[] = { 1, 1, 2, 2, 3, 3, 4, 5} 
            k = 3
Output : 5 7

Input : arr[] = { 1, 2, 2, 3} 
            k = 2
Output : 0 1

Input : arr[] = {1, 1, 2, 1, 2}
            k = 3
Output : Invalid k

Approach 1 : (Brute Force Method)

The simplest approach in this problem is, try to generate all the subarrays and check for which subarray the size is k. But there are some points we need to take care.

Steps:

  1. Pick each of the elements from the given array as the starting element [ i-th element ] of our required subarray.
  2. In each iteration initialize an empty set to store the distinct elements of the subarray
    • Pick each remaining element [ i, i+1,..n – 1] from the array as the last element [ j-th element ].
    • Add the current element to the set.
    • If the set size equals k then update the results and break from the inner loop (already found k distinct elements increasing the size of the subarray has 2 possibilities either will get more distinct elements, or increase the subarray size with repeated elements which are not to be considered in the required results).
  3. If (j == n) or j = size of the array, i.e. we have not found any desired subarray starting from i-th index and going forward we will be having fewer elements to consider.
    ( For example : consider given array is 4 5 5 4 5  and k = 3, when start from 0th index we will not find any subarray of k size and j will reach end so that means we won’t get any element that can make a k = 3 size required subarray). 
    So, Break from the outer loop.
  4. Print the output if found, otherwise, print “Invalid k”.

Implementation:

C++




// C++ program to find minimum range that
// contains exactly k distinct numbers.
#include <bits/stdc++.h>
using namespace std;
 
// Prints the minimum range that contains exactly
// k distinct numbers.
void minRange(int arr[], int n, int k)
{
    // Starting and ending  index of resultant subarray
    int start = 0, end = n;
 
    // Selecting each element as the start index for
    // subarray
    for (int i = 0; i < n; i++) {
        // Initialize a set to store all distinct elements
        unordered_set<int> set;
 
        // Selecting the end index for subarray
        int j;
        for (j = i; j < n; j++) {
            set.insert(arr[j]);
 
            /*
            If set contains exactly k elements,
            then check subarray[i, j] is smaller in size
            than the current resultant subarray
            */
            if (set.size() == k) {
                if (j - i < end - start) {
                    start = i;
                    end = j;
                }
 
                // There are already k distinct elements
                // now, no need to consider further elements
                break;
            }
        }
 
        // If there are no k distinct elements
        // left in the array starting from index i we will
        // break
        if (j == n) {
            break;
        }
    }
 
    // If no window found then print -1
    if (start == 0 && end == n)
        cout << "Invalid k";
 
    else
        cout << start << " " << end;
}
 
// Driver code for above function.
int main()
{
    int arr[] = { 1, 2, 3, 4, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = 3;
    minRange(arr, n, k);
    return 0;
}
 
// This code is contributed by Rajdeep


Java




// Java program to find minimum
// range that contains exactly
// k distinct numbers.
import java.util.*;
import java.util.ArrayList;
import java.util.HashSet;
 
class GFG {
 
    // Prints the minimum range
    // that contains exactly k
    // distinct numbers.
    static void minRange(int arr[], int n, int k)
    {
        // start -> start index of resultant subarray
        // end   -> end index of resultant subarray
        int start = 0;
        int end = n;
 
        // Selecting each element as the start index for
        // subarray
        for (int i = 0; i < n; i++) {
            // Initialize a set to store all distinct
            // elements
            HashSet<Integer> set = new HashSet<Integer>();
 
            // Selecting the end index for subarray
            int j;
            for (j = i; j < n; j++) {
                set.add(arr[j]);
 
                /*
                      If set contains exactly k
                    elements,then check subarray[i, j]
                    is smaller in size than the current
                    resultant subarray
                */
               
                if (set.size() == k)
                {
                    if (j - i < end - start) {
                        start = i;
                        end = j;
                    }
 
                    // There are already 'k' distinct
                    // elements now, no need to consider
                    // further elements
                    break;
                }
            }
 
            // If there are no k distinct elements left
              // in the array starting from index i we will break
            if (j == n)
                break;
        }
         
          // If no window found then print -1
        if (start == 0 && end == n)
            System.out.println("Invalid k");
 
        else
            System.out.println(start + " " + end);
    }
 
    // Driver code
    public static void main(String args[])
    {
        int arr[] = { 1, 2, 3, 4, 5 };
        int n = arr.length;
        int k = 3;
        minRange(arr, n, k);
    }
}
 
// This code is contributed by Rajdeep


Python 3




# Python 3 program to find minimum range
# that contains exactly k distinct numbers.
 
# Prints the minimum range that contains
# exactly k distinct numbers.
def minRange(arr, n, k):
 
    l = 0
    r = n
 
    # Consider every element as
    # starting point.
    for i in range(n):
 
        # Find the smallest window starting
        # with arr[i] and containing exactly
        # k distinct elements.
        s = []
        for j in range(i, n) :
            s.append(arr[j])
            if (len(s) == k):
                if ((j - i) < (r - l)) :
                    r = j
                    l = i
                 
                break
 
        # There are less than k distinct
        # elements now, so no need to continue.
        if (j == n):
            break
 
    # If there was no window with k distinct
    # elements (k is greater than total
    # distinct elements)
    if (l == 0 and r == n):
        print("Invalid k")
    else:
        print(l, r)
 
# Driver code
if __name__ == "__main__":
     
    arr = [ 1, 2, 3, 4, 5 ]
    n = len(arr)
    k = 3
    minRange(arr, n, k)
 
# This code is contributed
# by ChitraNayal


C#




// C#  program to find minimum 
// range that contains exactly 
// k distinct numbers.
using System;
using System.Collections.Generic;
 
public class GFG
{
 
// Prints the minimum range 
// that contains exactly k 
// distinct numbers.
public static void minRange(int[] arr, int n, int k)
{
    int l = 0, r = n;
 
    // Consider every element 
    // as starting point.
    for (int i = 0; i < n; i++)
    {
 
        // Find the smallest window 
        // starting with arr[i] and 
        // containing exactly k 
        // distinct elements.
        ISet<int> s = new HashSet<int>();
        int j;
        for (j = i; j < n; j++)
        {
            s.Add(arr[j]);
            if (s.Count == k)
            {
                if ((j - i) < (r - l))
                {
                    r = j;
                    l = i;
                }
                break;
            }
        }
 
        // There are less than k 
        // distinct elements now, 
        // so no need to continue.
        if (j == n)
        {
            break;
        }
    }
 
    // If there was no window 
    // with k distinct elements 
    // (k is greater than total 
    // distinct elements)
    if (l == 0 && r == n)
    {
        Console.WriteLine("Invalid k");
    }
    else
    {
        Console.WriteLine(l + " " + r);
    }
}
 
// Driver code 
public static void Main(string[] args)
{
    int[] arr = new int[] {1, 2, 3, 4, 5};
    int n = arr.Length;
    int k = 3;
    minRange(arr, n, k);
}
}
 
// This code is contributed by Shrikant13


Javascript




<script>
// Javascript program to find minimum
// range that contains exactly
// k distinct numbers.
     
    // Prints the minimum range
    // that contains exactly k
    // distinct numbers.
    function minRange(arr,n,k)
    {
        let l = 0, r = n;
  
    // Consider every element
    // as starting point.
    for (let i = 0; i < n; i++)
    {
  
        // Find the smallest window
        // starting with arr[i] and
        // containing exactly k
        // distinct elements.
        let s = new Set();
        let j;
        for (j = i; j < n; j++)
        {
            s.add(arr[j]);
            if (s.size == k)
            {
                if ((j - i) < (r - l))
                {
                    r = j;
                    l = i;
                }
                break;
            }
        }
  
        // There are less than k
        // distinct elements now,
        // so no need to continue.
        if (j == n)
            break;
    }
  
    // If there was no window
    // with k distinct elements
    // (k is greater than total
    // distinct elements)
    if (l == 0 && r == n)
        document.write("Invalid k");
    else
        document.write(l + " " + r);
    }
     
    // Driver code
    let arr=[1, 2, 3, 4, 5];
    let n = arr.length;
    let k = 3;
    minRange(arr, n, k);
     
     
    // This code is contributed by avanitrachhadiya2155
</script>


Output

0 2

Time Complexity : O(N^2) ,where N is the number of elements in the array. Every time picking the end points of the subarray using two nested loops(one inside another) makes the time complexity O(N^2).
Space Complexity :  O(N), In the worst case, we can have all ‘N’ elements in our set.

Approach 2 : (Sliding Window Approach)

Optimization is get rid of the repeated work while making all subarray, all subarray will not help to find the resultant. The approach is –

Steps :

  • Initialize a map to store the frequencies of each element.
  • Taking two variables as taken before : start and end of the required subarray.
  • And here we are using i and j as the starting and ending index of the window respectively, initializing as i = 0 and j = 0.
  • Will traverse the array while the ending pointer of our window reach the end of given array. i.e.  while( j < n)
    1. Add the current element to the map map[ arr[j] ]++ and make j pointing to the next index
    2. Consider the window [ i, j-1 ] (reason for ‘j-1’ is as we incremented the value of ‘j’ just after insertion in last step) check whether its size is equal to k
    3. If window size is lesser than k then continue
    4. But if window size == k, then check its length whether it is the resultant subarray or not. 
    5. After that we need to move our window, but in order to move our window, we have to check the starting element of our current window (i.e. i-th). If the i-th element is having a frequency of 1 then erase it from the map and else decrease its frequency by 1. And increase the i-value. Make i to point to the next element.

( For understanding the reason of erase and decreasing frequency, take an example :  4 2 2 3 4 4 3 and k = 3  when we are dealing with the window 2 2 3 4 then ‘i’ would have pointed to the start of window (first 2) and ‘j’ would have pointed to the last of window (at 4). Now while moving forward (by one position), if the window totally erase 2 from the map, (and make window 2 3 4 4) then map would contain the information that 2 is not in the map but it is wrong so we will decrease the count of 2. Similarly, in case of having frequency == 1, and about to leave the window, the map should not contain the frequency of the element which not there in the window. )

Implementation:

C++




// C++ program to find minimum range that
// contains exactly k distinct numbers.
#include <bits/stdc++.h>
using namespace std;
 
// prints the minimum range that contains exactly
// k distinct numbers.
void minRange(int arr[], int n, int k)
{
    /*
        start = starting index of resultant subarray
        end  = ending index of resultant subarray
    */
    int start = 0, end = n;
 
    unordered_map<int, int> map;
 
    /*
        i = starting index of the window (on left side)
        j = ending index of the window (on right side)
    */
    int i = 0, j = 0;
 
    while (j < n) {
        // Add the current element to the map
        map[arr[j]]++;
        j++;
 
        // Nothing to do when having less element
        if (map.size() < k)
            continue;
 
        /*
                If map contains exactly k elements,
                consider subarray[i, j - 1] keep removing
                left most elements
        */
 
        while (map.size() == k) {
            // as considering the (j-1)th and i-th index
            int windowLen = (j - 1) - i + 1;
            int subArrayLen = end - start + 1;
 
            if (subArrayLen > windowLen) {
                start = i;
                end = j - 1;
            }
 
            // Remove elements from left
 
            // If freq == 1 then totally erase
            if (map[arr[i]] == 1)
                map.erase(arr[i]);
 
            // decrease freq by 1
            else
                map[arr[i]]--;
 
            // move the starting index of window
            i++;
        }
    }
 
    if (start == 0 && end == n)
        cout << "Invalid k" << endl;
 
    else
        cout << start << " " << end << endl;
}
 
// Driver code for above function.
int main()
{
    int arr[] = { 1, 1, 2, 2, 3, 3, 4, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = 3;
    minRange(arr, n, k);
    return 0;
}
 
// This code is contributed by Rajdeep


Java




// Java program to find minimum range that
// contains exactly k distinct numbers.
import java.util.*;
 
class GFG {
 
    // Prints the minimum range that contains exactly
    // k distinct numbers.
    static void minRange(int arr[], int n, int k)
    {
 
        /*
            start = starting index of resultant subarray
            end  = ending index of resultant subarray
        */
        int start = 0, end = n;
 
        HashMap<Integer, Integer> map = new HashMap<>();
 
        /*
            i = starting index of the window (on left side)
            j = ending index of the window (on right side)
        */
        int i = 0, j = 0;
       
        while (j < n) {
           
            // Add the current element to the map
            map.put(arr[j], map.getOrDefault(arr[j], 0) + 1);
            j++;
           
              // Nothing to do when having less element
            if (map.size() < k)
                continue;
 
            /*
                If map contains exactly k elements,
                consider subarray[i, j - 1] keep removing
                left most elements
                */
            while (map.size() == k)
            {
                  // as considering the (j-1)th and i-th index
                int windowLen = (j - 1) - i + 1;
                int subArrayLen = end - start + 1;
               
                if (windowLen < subArrayLen) {
                    start = i;
                    end = j - 1;
                }
 
                // Remove elements from left
               
                  // If freq == 1 then totally erase
                if (map.get(arr[i]) == 1)
                    map.remove(arr[i]);
                 
                  // decrease freq by 1
                else
                    map.put(arr[i], map.get(arr[i]) - 1);
                 
                  // move the starting index of window
                i++;
            }
        }
 
        if (start == 0 && end == n)
            System.out.println("Invalid k");
       
        else
            System.out.println(start + " " + end);
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int arr[] = { 1, 1, 2, 2, 3, 3, 4, 5 };
        int n = arr.length;
        int k = 3;
 
        minRange(arr, n, k);
    }
}
 
// This code is contributed by Rajdeep


Python3




# Python3 program to find the minimum range
# that contains exactly k distinct numbers.
from collections import defaultdict
 
# Prints the minimum range that contains
# exactly k distinct numbers.
def minRange(arr, n, k):
  
    # Initially left and right side is -1
    # and -1, number of distinct elements
    # are zero and range is n.
    l, r = 0, n
    i = 0
    j = -1 # Initialize right side
     
    hm = defaultdict(lambda:0)
    while i < n:
      
        while j < n:
          
            # increment right side.
            j += 1
   
            # if number of distinct elements less than k.
            if len(hm) < k and j < n:
                hm[arr[j]] += 1
   
            # if distinct elements are equal to k
            # and length is less than previous length.
            if len(hm) == k and ((r - l) >= (j - i)):
              
                l, r = i, j
                break
   
        # if number of distinct elements less
        # than k, then break.
        if len(hm) < k:
            break
   
        # if distinct elements equals to k then
        # try to increment left side.
        while len(hm) == k:
   
            if hm[arr[i]] == 1:
                del(hm[arr[i]])
            else:
                hm[arr[i]] -= 1
   
            # increment left side.
            i += 1
   
            # it is same as explained in above loop.
            if len(hm) == k and (r - l) >= (j - i):
              
                l, r = i, j
          
        if hm[arr[i]] == 1:
            del(hm[arr[i]])
        else:
            hm[arr[i]] -= 1
             
        i += 1
   
    if l == 0 and r == n:
        print("Invalid k")
    else:
        print(l, r)
  
# Driver code for above function.
if __name__ == "__main__":
  
    arr = [1, 1, 2, 2, 3, 3, 4, 5
    n = len(arr)
    k = 3
    minRange(arr, n, k)
     
# This code is contributed by Rituraj Jain


C#




// C# program to find minimum
// range that contains exactly
// k distinct numbers.
using System;
using System.Collections.Generic;
class GFG{
     
// Prints the minimum
// range that contains exactly
// k distinct numbers.
static void minRange(int []arr,
                     int n, int k)
{
  // Initially left and
  // right side is -1 and -1,
  // number of distinct
  // elements are zero and
  // range is n.
  int l = 0, r = n;
 
  // Initialize right side
  int j = -1;
 
  Dictionary<int,
             int> hm = new Dictionary<int,
                                      int>();
 
  for(int i = 0; i < n; i++)
  {
    while (j < n)
    {
      // Increment right side.
      j++;
 
      // If number of distinct elements less
      // than k.
      if (j < n && hm.Count < k)
        if(hm.ContainsKey(arr[j]))
          hm[arr[j]] = hm[arr[j]] + 1;
      else
        hm.Add(arr[j], 1);
 
      // If distinct elements are equal to k
      // and length is less than previous length.
      if (hm.Count == k &&
         ((r - l) >= (j - i)))
      {
        l = i;
        r = j;
        break;
      }
    }
 
    // If number of distinct elements less
    // than k, then break.
    if (hm.Count < k)
      break;
 
    // If distinct elements equals to k then
    // try to increment left side.
    while (hm.Count == k)
    {
      if (hm.ContainsKey(arr[i]) && 
          hm[arr[i]] == 1)
        hm.Remove(arr[i]);
      else
      {
        if(hm.ContainsKey(arr[i]))
          hm[arr[i]] = hm[arr[i]] - 1;
      }
 
      // Increment left side.
      i++;
 
      // It is same as explained in above loop.
      if (hm.Count == k &&
         (r - l) >= (j - i))
      {
        l = i;
        r = j;
      }
    }
    if (hm.ContainsKey(arr[i]) && 
        hm[arr[i]] == 1)
      hm.Remove(arr[i]);
    else
      if(hm.ContainsKey(arr[i]))
        hm[arr[i]] = hm[arr[i]] - 1;
  }
 
  if (l == 0 && r == n)
    Console.WriteLine("Invalid k");
  else
    Console.WriteLine(l + " " + r);
}
 
// Driver code
public static void Main(String[] args)
{
  int []arr = {1, 1, 2, 2,
               3, 3, 4, 5};
  int n = arr.Length;
  int k = 3;
  minRange(arr, n, k);
}
}
 
// This code is contributed by shikhasingrajput


Javascript




<script>
// Javascript program to find minimum
// range that contains exactly
// k distinct numbers
     
     
    // Prints the minimum
// range that contains exactly
// k distinct numbers.
    function minRange(arr,n,k)
    {
        // Initially left and right side is -1 and -1,
    // number of distinct elements are zero and
    // range is n.
    let l = 0, r = n;
      
    // Initialize right side
    let j = -1;
      
    let hm = new Map();
      
    for(let i = 0; i < n; i++)
    {
        while (j < n)
        {
              
            // Increment right side.
            j++;
  
            // If number of distinct elements less
            // than k.
            if (j < n && hm.size < k)
            {
                if(hm.has(arr[j]))
                    hm.set(arr[j],
                       hm.get(arr[j]) + 1);
                else
                    hm.set(arr[j],1);
             
             }
            // If distinct elements are equal to k
            // and length is less than previous length.
            if (hm.size == k &&
                 ((r - l) >= (j - i)))
            {
                l = i;
                r = j;
                break;
            }
        }
  
        // If number of distinct elements less
        // than k, then break.
        if (hm.size < k)
            break;
  
        // If distinct elements equals to k then
        // try to increment left side.
        while (hm.size == k)
        {
            if (hm.has(arr[i]) && hm.get(arr[i]) == 1)
                hm.delete(arr[i]);
            else
                if(hm.has(arr[i]))
                    hm.set(arr[i],hm.get(arr[i]) - 1);
  
            // Increment left side.
            i++;
  
            // It is same as explained in above loop.
            if (hm.size == k &&
                  (r - l) >= (j - i))
            {
                l = i;
                r = j;
            }
        }
        if (hm.has(arr[i]) && hm.get(arr[i]) == 1)
            hm.delete(arr[i]);
        else
            if(hm.has(arr[i]))
                hm.set(arr[i],hm.get(arr[i]) - 1);
    }
  
    if (l == 0 && r == n)
        document.write("Invalid k");
    else
        document.write(l + " " + r);
    }
     
     
    // Driver code
    let arr=[1, 1, 2, 2, 3, 3, 4, 5];
    let n = arr.length;
    let k = 3;
    minRange(arr, n, k);
     
    // This code is contributed by rag2127
</script>


Output

5 7

Time Complexity : O(N) ,where N is the number of elements in the array. In the worst case, each element will be added once and removed once from the map.
Space Complexity :  O(K), In the worst case, we can have only ‘K’ elements in our map.

 



Previous Article
Next Article

Similar Reads

Smallest pair of indices with product of subarray co-prime with product of the subarray on the left or right
Given an array arr[] of length N, the task is to find the smallest pair of indices (i, j) such that the product of elements in the subarray arr[i + 1, j - 1] is co-prime with either the product of the subarray arr[0, i] or that of the subarray arr[j, N]. If no such pair exists, the print "-1". Examples: Input: arr[] = {2, 4, 1, 3, 7}Output: (0, 2)E
12 min read
Length of longest subarray having only K distinct Prime Numbers
Given an array arr[] consisting of N positive integers. The task is to find the length of the longest subarray of this array that contains exactly K distinct Prime Numbers. If there doesn't exist any subarray, then print "-1". Examples: Input: arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}, K = 1Output: 4Explanation:The subarray {6, 7, 8, 9} contains 4 elemen
15+ min read
Find distinct characters in distinct substrings of a string
Given a string str, the task is to find the count of distinct characters in all the distinct sub-strings of the given string.Examples: Input: str = "ABCA" Output: 18 Distinct sub-stringsDistinct charactersA1AB2ABC3ABCA3B1BC2BCA3C1CA2 Hence, 1 + 2 + 3 + 3 + 1 + 2 + 3 + 1 + 2 = 18Input: str = "AAAB" Output: 10 Approach: Take all possible sub-strings
5 min read
Print all distinct integers that can be formed by K numbers from a given array of N numbers
Given an array of N elements and an integer K, print all the distinct integers which can be formed by choosing K numbers from the given N numbers. A number from an array can be chosen any number of times. Examples: Input: k = 2, a[] = {3, 8, 17, 5} Output: The 10 distinct integers are: 6 8 10 11 13 16 20 22 25 34 The 2 elements chosen are: 3+3 = 6,
7 min read
Numbers less than N which are product of exactly two distinct prime numbers
Given a number [Tex]N [/Tex]. The task is to find all such numbers less than N and are a product of exactly two distinct prime numbers. For Example, 33 is the product of two distinct primes i.e 11 * 3, whereas numbers like 60 which has three distinct prime factors i.e 2 * 2 * 3 * 5.Note: These numbers cannot be a perfect square.Examples: Input : N
8 min read
Find prime factors of Z such that Z is product of all even numbers till N that are product of two distinct prime numbers
Given a number N (N &gt; 6), the task is to print the prime factorization of a number Z, where Z is the product of all numbers ≤ N that are even and can be expressed as the product of two distinct prime numbers. Example: Input: N = 6Output: 2→1 3→1Explanation: 6 is the only number ≤ N, which is even and a product of two distinct prime numbers (2 an
7 min read
Bitwise XOR of first N natural numbers that are product of two distinct Prime Numbers
Given a positive integer N, the task is to calculate the Bitwise XOR of first N numbers which are a product of exactly two distinct prime numbers. Examples: Input: N = 20Output: 7Explanation: The numbers from the range [1, 20] which are a product of exactly two distinct prime numbers are {6, 10, 12, 14, 15, 18, 20}.Bitwise XOR of these numbers = 6
8 min read
Maximum sum of distinct numbers such that LCM of these numbers is N
Given a positive number N. The task is to find the maximum sum of distinct numbers such that the LCM of all these numbers is equal to N. Examples: Input : 2 Output : 3 The distinct numbers you can have are just 1 and 2 and their sum is equal to 3. Input : 5 Output : 6Recommended PracticeMaximum Sum LCMTry It! As the LCM of all the numbers is N. So
4 min read
Queries for number of distinct elements in a subarray | Set 2
Given an array arr[] of N integers and Q queries. Each query can be represented by two integers L and R. The task is to find the count of distinct integers in the subarray arr[L] to arr[R].Examples: Input: arr[] = {1, 1, 3, 3, 5, 5, 7, 7, 9, 9 }, L = 0, R = 4 Output: 3Input: arr[] = { 1, 1, 2, 1, 3 }, L = 1, R = 3 Output : 2 Naive approach: In this
13 min read
Longest subarray with difference exactly K between any two distinct values
Given an array arr[] of length N and an integer K, the task is to find the longest subarray with difference between any two distinct values equal to K. Print the length of the longest subarray obtained. Otherwise, if no such subarray is obtained, print -1. Examples: Input: arr[] = {0, 0, 1, 1, 3, 3, 3}, K = 1 Output: 4 Explanation: The subarray {0,
12 min read
Practice Tags :