Smallest Subarray With K Distinct Numbers in Java

An array containing integers is given to us. Also, an integer k is given. Our task is to find the array comprising of the minimum range [lft, rght], (both lft and rght are inclusive in the range), such that exactly k different numbers are there in the range. If it is not possible to find the k different elements in the given input array, then a suitable message should be shown on the console. Observe the following examples.

Example 1:

Input

arr[] = { 11, 11, 11, 12, 12, 13, 13, 14, 15, 17 }, k = 4

Output: {6, 9}

Explanation: The range [6, 9] consists of four distinct elements. Also, this window size or the range size is the smallest.

Example 2:

Input

arr[] = { 11, 12, 12, 13}, k = 3

Output: {0, 3}

Explanation: The range [0, 3] contains three distinct elements. Also, this window size or the range size is the smallest.

Example 3:

Input

arr[] = { 11, 12, 12, 12, 13, 13}, k = 5

Output: It is not possible to find the five distinct elements in the input array arr[].

Explanation: The input array only contains three distinct elements. Hence, finding five distinct elements is not possible.

Naïve Approach:

The naive approach of the problem is to find out all of the subarrays and then check whether the subarray is of the size k or not. However, there are some points that one needs to take into consideration.

Algorithm:

Step 1: Pick each element of the provided input array as the beginning element [j-th element] of the required subarray.

Step 2: In each iteration, create an empty set for keeping the unique sub-array elements.

  • Pick each of the remaining element [j, j + 1, … n - 1] from the input array as the last element [k-th element].
  • Insert the current element into the set.
  • If the size of the set is k, then exit from the inner loop and update the results (already found the k unique elements and increasing the subarray size has two possibilities either one will find more unique elements or one will increase the size of the subarray with the elements that are repeated and should be avoided in the results that are required).

Step 3: If (k == n), then it means any required subarray beginning from the jth index is not found. Therefore, the outer loop should be terminated.

Step 4: Display the found output if found. Else, an appropriate message should be printed on the console.

Implementation

Let's do the implementation of the above steps. Observe the following program.

FileName: SmallestSubarray.java

Output:

For the input array: 
11 11 11 12 12 13 13 14 15 17 
The smallest subarray containing 4 distinct elements ranges from: [6, 9] 
 
For the input array: 
11 12 12 13 
The smallest subarray containing 3 distinct elements ranges from: [0, 3] 
 
For the input array: 
11 12 12 12 13 13 
The smallest subarray containing 5 distinct elements is not found.

Complexity Analysis: The program uses the nested for-loop making the time complexity of the program O(n2). Also, the program uses the hash set, making the space complexity of the program O(n), where n is the total number of elements present in the input array.

Now, we will do some optimization to reduce the time and space complexity.

Approach: Sliding Window

Using the sliding window, we can reduce the time complexity, as well as, the space complexity of the program. But before writing the program, let's see the steps involved to achieve the result.

Step 1: Create a map for keeping the number of occurrences of each element.

Step 2: Take two variables: st and ed, of the required subarray.

Step 3: Here, we will use j and k as the beginning point and the ending point of the window, respectively, and assign j = 0 and k = 0.

Step 4: Traverse the input array till the end pointer (k) of the window reaches the end of the input array. i.e., while( k < n) do the following:

  1. Put the current element to the map mp[ inputArr[k] ]++ and make k point to the next index
  2. Check whether the window [j, k - 1] size the equal to k or not.
  3. Continue If the size of the window is lesser than k.
  4. But if the size of the window (size == k), then check the length whether it is the required subarray or not. If yes, update variables st and ed.
  5. After that, move the window, but to move the window, one has to check the beginning element of the current window (i.e. j-th). If the j-th element is of the frequency 1, then remove it from the map and otherwise reduce its frequency by 1.

Implementation

Let's see the implementation of the above steps.

FileName: SmallestSubarray1.java

Output:

For the input array: 
11 11 11 12 12 13 13 14 15 17 
The smallest subarray containing 4 distinct elements ranges from: [6, 9] 
 
For the input array: 
11 12 12 13 
The smallest subarray containing 3 distinct elements ranges from: [0, 3] 
 
For the input array: 
11 12 12 12 13 13 
The smallest subarray containing 5 distinct elements is not found.

Complexity Analysis: In the worst-case scenario, an element can be added or removed from the hash map only once. Thus, the time complexity of the program is O(n), where n is the total number of elements present in the input array. In the worst case, the hash map can only have k elements. Thus, the space complexity of the program is O(k).






Latest Courses