Top K Frequent Elements Problem

Top K Frequent Elements Problem

Given an integer array nums and an integer k, return the k most frequent elements within the array.

The test cases are generated such that the answer is always unique.

You may return the output in any order.

Top K Frequent Elements

Constraints:

  • 1 <= nums.length <= 10^4
  • -1000 <= nums[i] <= 1000
  • 1 <= k <= number of distinct elements in nums.

Top K Frequent Elements Solution

Recommendation – You should aim for a solution with O(n) time and O(n) space, where n is the size of the input array.

Hints for solving problems

Hint 1 :

A naive solution would be to count the frequency of each number and then sort the array based on each element’s frequency. After that, we would select the top k frequent elements. This would be an O(nlogn) solution. Though this solution is acceptable, can you think of a better way?

Hint 2:

Can you think of an algorithm which involves grouping numbers based on their frequency?

Hint 3:

Use the bucket sort algorithm to create n buckets, grouping numbers based on their frequencies from 1 to n. Then, pick the top k numbers from the buckets, starting from n down to 1.

There are mainly 3 approach to solve this problem 

  1. Sorting Method
  2. Heap Method
  3. Bucket Sort Method

1. Sorting Method

This method counts the frequency of each element using a hash map, then sort the elements by frequency in descending order and pick the top K elements.

  • Time complexity: O(nlog n)
  • Space complexity: O(n)

Code

class Solution {
public:
    vector topKFrequent(vector& nums, int k) {
        unordered_map count;
        for (int num : nums) {
            count[num]++;
        }

        vector> arr;
        for (const auto& p : count) {
            arr.push_back({p.second, p.first});
        }
        sort(arr.rbegin(), arr.rend());

        vector res;
        for (int i = 0; i < k; ++i) {
            res.push_back(arr[i].second);
        }
        return res;
    }
};

2. Heap Method

This method use a min-heap to store the K most frequent elements. Iterate through the frequency map, adding elements to the heap while maintaining its size at K.

  • Time complexity: O(nlogk)
  • Space complexity: O(n+k)

where n is the length of the array and k is the number of top frequent elements.

Code

class Solution {
public:
    vector topKFrequent(vector& nums, int k) {
        unordered_map count;
        for (int num : nums) {
            count[num]++;
        }

        priority_queue, vector>, greater>> heap;
        for (auto& entry : count) {
            heap.push({entry.second, entry.first});
            if (heap.size() > k) {
                heap.pop();
            }
        }

        vector res;
        for (int i = 0; i < k; i++) {
            res.push_back(heap.top().second);
            heap.pop();
        }
        return res;
    }
};

3. Bucket Sort Method

This method group elements by their frequency in buckets (arrays), then iterate through the buckets from highest to lowest frequency to extract the top K elements.

  • Time complexity: O(n)
  • Space complexity: O(n)

Code

class Solution {
public:
    vector topKFrequent(vector& nums, int k) {
        unordered_map count;
        vector> freq(nums.size() + 1);

        for (int n : nums) {
            count[n] = 1 + count[n];
        }
        for (const auto& entry : count) {
            freq[entry.second].push_back(entry.first);
        }

        vector res;
        for (int i = freq.size() - 1; i > 0; --i) {
            for (int n : freq[i]) {
                res.push_back(n);
                if (res.size() == k) {
                    return res;
                }
            }
        }
        return res;
    }
};

More Articles