Grokking the Coding Interview: Patterns for Coding Questions
Ask Author
Back to course home

0% completed

Vote For New Content
Solution: Maximum Distinct Elements
Table of Contents

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible

Problem Statement

Given an array of numbers nums and an integer K, find the maximum number of distinct elements after removing exactly K elements from the nums array.

Example 1:

  • Input: nums = [7, 3, 5, 8, 5, 3, 3], K=2
  • Expected Output: 3
  • Explanation: We can remove two occurrences of 3 to be left with 3 distinct numbers [7, 3, 8], we have to skip 5 because it is not distinct and occurred twice. Another solution could be to remove one instance of '5' and '3' each to be left with three distinct numbers [7, 5, 8], in this case, we have to skip 3 because it occurred twice.

Example 2:

  • Input: [3, 5, 12, 11, 12], and K=3
  • Expected Output: 2
  • Explanation: We can remove one occurrence of 12, after which all numbers will become distinct. Then we can delete any two numbers which will leave us 2 distinct numbers in the result.

Example 3:

  • Input: [1, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5], and K=2
  • Expected Output: 3
  • Explanation: We can remove one occurrence of '4' to get three distinct numbers 1, 2 and 4.

Constraints:

  • 1 <= arr.length <= 10<sup>5</sup>
  • 1 <= arr[i] <= 10<sup>9</sup>
  • 0 <= k <= arr.length

Solution

This problem follows the Top ‘K’ Numbers pattern, and shares similarities with Top ‘K’ Frequent Numbers.

To solve this problem, we need to determine the maximum number of distinct elements that can be left in the array after removing k elements. The core idea is to prioritize the removal of elements with higher frequencies first, as this will maximize the number of distinct elements remaining. By reducing the frequency of these elements, we can potentially convert them into distinct elements.

The algorithm starts by calculating the frequency of each element in the array. Then, we use a min-heap (priority queue) to store elements based on their frequencies in ascending order. This allows us to efficiently access and remove the least frequent elements first. For each element in the min-heap, we reduce its frequency by removing occurrences until either all occurrences are removed or k elements have been removed. Finally, if there are any removals left (k > 0), we decrement the count of distinct elements accordingly.

Step-by-Step Algorithm

  1. Initialize Frequency Map:

    • Create a map to store the frequency of each element in the array.
    • Iterate through the array, updating the frequency of each element in the map.
  2. Create Min-Heap:

    • Initialize a min-heap (priority queue) to store elements based on their frequency.
    • Iterate through the frequency map:
      • If an element's frequency is 1, increment the count of distinct elements.
      • If an element's frequency is greater than 1, add it to the min-heap.
  3. Remove Elements:

    • While k is greater than 0 and the min-heap is not empty:
      • Extract the element with the lowest frequency from the heap.
      • Calculate the number of occurrences to be removed (frequency - 1).
      • Decrement k by this number.
      • If k is non-negative, increment the count of distinct elements.
  4. Adjust Distinct Count:

    • If k is still greater than 0 after processing the min-heap, decrement the count of distinct elements by k. It removes remaining elements from the distinct elements.
  5. Return Result:

    • Return the count of distinct elements.

Algorithm Walkthrough

Let's walk through the algorithm using the example: nums = [7, 3, 5, 8, 5, 3, 3], k = 2.

  1. Initialize Frequency Map:

    • Initialize an empty map to store the frequency of each element.
    • Iterate through the array and update the map:
      • 7: frequency 1
      • 3: frequency 1 (initially), then 2, then 3
      • 5: frequency 1 (initially), then 2
      • 8: frequency 1
    • Final frequency map: {7: 1, 3: 3, 5: 2, 8: 1}
  2. Create Min-Heap:

    • Initialize a min-heap (priority queue).
    • Initialize distinctElementsCount = 0.
    • Iterate through the frequency map:
      • 7: frequency is 1, increment distinctElementsCount to 1.
      • 3: frequency is 3, add to the min-heap.
      • 5: frequency is 2, add to the min-heap.
      • 8: frequency is 1, increment distinctElementsCount to 2.
    • Final distinct elements count before processing heap: 2
    • Final min-heap: [(5, 2), (3, 3)] (elements are tuples of (frequency, element))
  3. Remove Elements:

    • While k is greater than 0 and the min-heap is not empty:
      • Extract the element with the lowest frequency from the heap:
        • Pop (5, 2) from the heap.
        • To make element 5 distinct, remove 2 - 1 = 1 occurrence.
        • Decrement k by 1 (k = 2 - 1 = 1).
        • Since k is non-negative, increment distinctElementsCount to 3.
      • Extract the next element with the lowest frequency from the heap:
        • Pop (3, 3) from the heap.
        • To make element 3 distinct, remove 3 - 1 = 2 occurrences.
        • Decrement k by 2 (k = 1 - 2 = -1).
        • Since k is now negative, do not increment distinctElementsCount.
  4. Adjust Distinct Count:

    • Since k is not greater than 0 after processing the heap, no need to decrement distinctElementsCount.
    • distinctElementsCount remains 3.
  5. Return Result:

    • Return distinctElementsCount, which is 3.

So, the maximum number of distinct elements after removing 2 elements from [7, 3, 5, 8, 5, 3, 3] is 3.

Code

Here is what our algorithm will look like:

Python3
Python3

. . . .

Complexity Analysis

Time Complexity

  1. Frequency Map Construction: Building the frequency map requires iterating through the array, which takes O(N) time, where (N) is the number of elements in the array.

  2. Min-Heap Construction: Inserting elements into the min-heap based on their frequencies. Each insertion operation into the heap takes O(N\log N) time.

  3. Removing Elements: Removing elements from the min-heap and updating the count takes O(K \log N) time, where (K) is the number of elements to remove. This is because each removal operation from the heap takes O(\log N) time, and in the worst case, we might remove (K) elements.

Therefore, the overall time complexity is: O(N) + O(NlogN) + O(K \log N) Since (K) can be at most (N), this simplifies to: O(N \log N)

Space Complexity

  1. Frequency Map: The space required to store the frequency map is O(N) since, in the worst case, each element in the array is distinct.

  2. Min-Heap: The space required to store the elements in the min-heap is O(N) since, in the worst case, all elements might be inserted into the heap.

Therefore, the overall space complexity is: O(N) + O(N) = O(N)

.....

.....

.....

Like the course? Get enrolled and start learning!

Table of Contents

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible