Teaching Kids Programming – Reduce Array Size to The Half via Counting (Greedy, Hash Table)


Teaching Kids Programming: Videos on Data Structures and Algorithms

You are given an integer array arr. You can choose a set of integers and remove all the occurrences of these integers in the array. Return the minimum size of the set so that at least half of the integers of the array are removed.

Example 1:
Input: arr = [3,3,3,3,5,5,5,2,2,7]
Output: 2
Explanation: Choosing {3,7} will make the new array [5,5,5,2,2] which has size 5 (i.e equal to half of the size of the old array).
Possible sets of size 2 are {3,5},{3,2},{5,2}.
Choosing set {2,7} is not possible as it will make the new array [3,3,3,3,5,5,5] which has a size greater than half of the size of the old array.

Example 2:
Input: arr = [7,7,7,7,7,7]
Output: 1
Explanation: The only possible set you can choose is {7}. This will make the new array empty.

Constraints:
2 <= arr.length <= 10^5
arr.length is even.
1 <= arr[i] <= 10^5

Greedy Algorithms to Reduce Array Size to The Half via Counting (Hash Table)

We can do this greedily. We pick the most popular numbers first. In order to this, we have to count each number and we can do this via a Counter (hash map). Then as we pick the numbers, we check if we have picked at least half.

We can sort the counter’s values (the frequencies):

1
2
3
4
5
6
7
8
9
10
11
12
class Solution:
    def minSetSize(self, arr: List[int]) -> int:        
        c = Counter(arr)
        a = [y for x, y in c.items()]
        a.sort(reverse=True)
        ans = 0
        t = 0
        for i in a:
            ans += 1
            t += i
            if t * 2 >= len(arr):
                return ans
class Solution:
    def minSetSize(self, arr: List[int]) -> int:        
        c = Counter(arr)
        a = [y for x, y in c.items()]
        a.sort(reverse=True)
        ans = 0
        t = 0
        for i in a:
            ans += 1
            t += i
            if t * 2 >= len(arr):
                return ans

Another better approach is to use the most_common which gives us a list of most common elements and their frequencies (in a tuple).

1
a = (x for y, x in c.most_common())
a = (x for y, x in c.most_common())

The most_common method of a Counter returns a list of tuple (a, b) where a is the element and b is the frequency. And the list sorts the tuple in the order of frequencies from high to low.

We can use this to get the least common from the most common:

1
2
3
def least_common(s, n):
    c = Counter(s)
    return c.most_common()[:-n-1:-1]
def least_common(s, n):
    c = Counter(s)
    return c.most_common()[:-n-1:-1]

The most_common when supplied with a parameter N, returns the most/top common N elements.

The time complexity is O(NLogN) due to sorting – and the space complexity is O(N) as we are using a dictionary to count the numbers and their frequencies.

–EOF (The Ultimate Computing & Technology Blog) —

GD Star Rating
loading...
569 words
Last Post: Teaching Kids Programming - Algorithms to Count Equal Row and Column Pairs in a Square Matrix using Hash Map
Next Post: Cloudflare Worker Unexpected High Usage of API Requests - How to Avoid Surprising Billing?

The Permanent URL is: Teaching Kids Programming – Reduce Array Size to The Half via Counting (Greedy, Hash Table)

Leave a Reply