Top K Frequent in an Array

Last Updated : 18 Jan, 2026

Given an array arr[] and a positive integer k, Find the top k elements which have the highest frequency in the array.

Note: If more than one element has same frequency then priorities the larger element over the smaller one.

Examples: 

Input: arr[] = [3, 1, 4, 4, 5, 2, 6, 1], k = 2
Output: [4, 1]
Explanation: Frequency of 4 is 2 and frequency of 1 is 2, these two have the maximum frequency.

Input: arr[] = [7, 10, 11, 5, 2, 5, 5, 7, 11, 8, 9], k = 4
Output: [5, 11, 7, 10]
Explanation: Frequency of 5 is 3, frequency of 11 is 2, frequency of 7 is 2, and frequency of rest is 1 but 10 is largest .

Try It Yourself
redirect icon

[Naive Approach] Using Hash map and Sorting

The idea is to use a hashmap to store each element along with its frequency, allowing insertion and updates in constant time. After building the frequency map, sort the elements in decreasing order of their frequency. To find the top k elements, simply take the first k elements from the sorted list.

C++
//Driver Code Starts
#include <iostream>
#include <unordered_map>
#include <algorithm>
#include <vector>

using namespace std;
//Driver Code Ends


// Comparison function to sort the frequency array
static bool compare(pair<int, int> &p1, pair<int, int> &p2) {
    
    // Prioritise element's value incase their frequency was same
    if (p1.second == p2.second)
        return p1.first > p2.first;
    
    // Sort on the basis of decreasing order
    // of frequencies
    return p1.second > p2.second;
}

// Function to find k numbers with most occurrences
vector<int> topKFreq(vector<int>&arr,int k) {
    int n = arr.size();
    unordered_map<int, int> mp;
    for (int i = 0; i < n; i++)
        mp[arr[i]]++;

    // Store the elements of 'mp' in the vector 'freq'
    vector<pair<int, int>> freq(mp.begin(), mp.end());

    // Sort the vector 'freq' on the basis of the
    // 'compare' function
    sort(freq.begin(), freq.end(), compare);
    
    vector<int>res;
    
    // Extract and store the top k frequent elements
    for (int i = 0; i < k; i++)
        res.push_back(freq[i].first);
        
    return res;
}


//Driver Code Starts
int main() {
    
    vector<int> arr = {3, 1, 4, 4, 5, 2, 6, 1};
    int k = 2;
    vector<int> res = topKFreq(arr, k);
    
    for(int val : res)
        cout << val << " ";
    
}

//Driver Code Ends
Java
//Driver Code Starts
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;

class GFG {
//Driver Code Ends

    
    // Comparison function to sort the frequency array
    static class Compare implements Comparator<int[]> {
        public int compare(int[] p1, int[] p2) {
            
            // Prioritise element's 
            //value in case their frequency was same
            if (p1[1] == p2[1])
                return Integer.compare(p2[0], p1[0]);
            
            // Sort on the basis of decreasing order
            // of frequencies
            return Integer.compare(p2[1], p1[1]);
        }
    }

    // Function to find k numbers with most occurrences
    static ArrayList<Integer> topKFreq(int[] arr, int k) {
        int n = arr.length;
        
        Map<Integer, Integer> mp = new HashMap<>();
        for (int i = 0; i < n; i++)
            mp.put(arr[i], mp.getOrDefault(arr[i], 0) + 1);

        // Store the elements of 'mp' in the list 'freq'
        ArrayList<int[]> freq = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : mp.entrySet())
            freq.add(new int[]{entry.getKey(), entry.getValue()});

        // Sort the list 'freq' on the basis of the
        // 'compare' function
        freq.sort(new Compare());
        
        ArrayList<Integer> res = new ArrayList<>();
        for (int i = 0; i < k; i++) {
            res.add(freq.get(i)[0]);
        }

        return res;
    }


//Driver Code Starts
    public static void main(String[] args) {
        int[] arr = {3, 1, 4, 4, 5, 2, 6, 1};
        int k = 2;
        ArrayList<Integer> res = topKFreq(arr, k);
        
        for (int val : res)
            System.out.print(val + " ");
    }
}

//Driver Code Ends
Python
#Driver Code Starts
from collections import Counter
#Driver Code Ends


def topKFreq(arr, k):
    n = len(arr)

    mp = Counter(arr)

    # Store the elements of 'mp' in the list 'freq'
    freq = list(mp.items())

    # Sort the list 'freq' on the basis of the
    # 'compare' function
    freq.sort(key=lambda x: (x[1], x[0]), reverse=True)
    
    res = []
    
    # Extract and store the top k frequent elements
    for i in range(k):
        res.append(freq[i][0])
        
    return res


#Driver Code Starts
if __name__ == "__main__":
    arr = [3, 1, 4, 4, 5, 2, 6, 1]
    k = 2
    res = topKFreq(arr, k)
    
    for val in res:
        print(val, end=" ")

#Driver Code Ends
C#
//Driver Code Starts
using System;
using System.Collections.Generic;
using System.Linq;

class GFG {
//Driver Code Ends

    
    // Comparison function to sort the frequency array
    class FrequencyComparer : IComparer<int[]> {
        public int Compare(int[] p1, int[] p2) {
            
            // Prioritise element's value 
            // in case their frequency is same
            if (p1[1] == p2[1])
                return p2[0].CompareTo(p1[0]);

            // Sort on the basis of decreasing order
            // of frequencies
            return p2[1].CompareTo(p1[1]);
        }
    }

    // Function to find k numbers with most occurrences
    static List<int> topKFreq(int[] arr, int k) {
        int n = arr.Length;
        
        Dictionary<int, int> mp = new Dictionary<int, int>();
        foreach (int num in arr) {
            if (mp.ContainsKey(num))
                mp[num]++;
            else
                mp[num] = 1;
        }

        // Store the elements of 'mp' in the list 'freq'
        List<int[]> freq = new List<int[]>();
        foreach (var entry in mp)
            freq.Add(new int[] { entry.Key, entry.Value });

        // Sort the list 'freq' on the basis of the
        // 'FrequencyComparer' function
        freq.Sort(new FrequencyComparer());

        List<int> res = new List<int>();

        // Extract and store the top k frequent elements
        for (int i = 0; i < k; i++)
            res.Add(freq[i][0]);

        return res;
    }


//Driver Code Starts
    public static void Main() {
        int[] arr = { 3, 1, 4, 4, 5, 2, 6, 1 };
        int k = 2;
        List<int> res = topKFreq(arr, k);

        foreach (int val in res)
            Console.Write(val + " ");
    }
}

//Driver Code Ends
JavaScript
function compare(p1, p2) {
    
    // Prioritise element's value in case 
    //their frequency was same
    if (p1[1] === p2[1])
        return p2[0] - p1[0];
    
    // Sort on the basis of decreasing order
    // of frequencies
    return p2[1] - p1[1];
}

// Function to find k numbers with most occurrences
function topKFreq(arr, k) {
    let n = arr.length;

    let mp = {};
    for (let i = 0; i < n; i++)
        mp[arr[i]] = (mp[arr[i]] || 0) + 1;

    // Store the elements of 'mp' in the array 'freq'
    let freq = Object.entries(mp).map(([key, value]) => [parseInt(key), value]);

    // Sort the array 'freq' on the basis of the
    // 'compare' function
    freq.sort(compare);
    
    let res = [];
    
    // Extract and store the top k frequent elements
    for (let i = 0; i < k; i++)
        res.push(freq[i][0]);
        
    return res;
}


// Driver code
//Driver Code Starts
let arr = [3, 1, 4, 4, 5, 2, 6, 1];
let k = 2;
let res = topKFreq(arr, k);

console.log(res.join(" "));

//Driver Code Ends

Output
4 1 

Time Complexity: O(n +d*log d), where n is the size of the array and d is the count of distinct elements in the array.
Auxiliary Space: O(d)

[Expected Approach 1] Using Hash map and Min Heap

The idea is to use a hashmap to store each element and its frequency. Then, use a priority queue (min-heap) to store pairs of frequency and element, so that the element with the smallest frequency is on top. Iterate through the hashmap and push each pair into the heap, and if the heap size exceeds k, remove the top element. After processing all elements, the heap will contain the k most frequent elements. Finally, extract these elements from the heap and store them in the result array.

C++
#include <algorithm>
#include <iostream>
#include <queue>
#include <unordered_map>
#include <vector>
using namespace std;

vector<int> topKFreq(vector<int> &arr, int k) {

    unordered_map<int, int> mp;
    for (int val: arr)
        mp[val]++;

    // Min-heap to keep track of top k frequent elements
    //{frequency, element}
    priority_queue<pair<int, int>, 
    vector<pair<int, int>>, greater<pair<int, int>>> pq;
    
    for (pair<int, int> entry : mp) {
        
        // Push the current element and its frequency into heap
        pq.push({entry.second, entry.first});
        
        // If heap size exceeds k,
        //remove the element with smallest frequency
        if (pq.size() > k)
            pq.pop();
    }

    vector<int> res(k);

    // Extract elements from heap in descending frequency order
    for (int i = k-1; i >= 0; i--) {
        res[i] = pq.top().second;
        pq.pop();
    }
    
    return res;
}

int main() {

    vector<int> arr = {3, 1, 4, 4, 5, 2, 6, 1};
    int k = 2;

    vector<int> res = topKFreq(arr, k);

    for (int i = 0; i < res.size(); i++)
        cout << res[i] << " ";
}
Java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Collections;

class GFG {

    static ArrayList<Integer> topKFreq(int[] arr, int k)
    {
        HashMap<Integer, Integer> mp = new HashMap<>();
        for (int val : arr)
            mp.put(val, mp.getOrDefault(val, 0) + 1);

        // Min-heap to keep track of top k frequent elements
        // {frequency, element}
        PriorityQueue<int[]> pq = new PriorityQueue<>
                       ((a, b) -> a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]);

        for (Map.Entry<Integer, Integer> entry : mp.entrySet()) {
            // Push the current element and its frequency
            // into heap
            pq.add(new int[] { entry.getValue(), entry.getKey() });

            // If heap size exceeds k,
            // remove the element with smallest frequency
            if (pq.size() > k)
                pq.poll();
        }

        // Extract elements from heap in descending
        // frequency order
        ArrayList<Integer> res = new ArrayList<>();
        while (!pq.isEmpty()) {
            res.add(pq.poll()[1]);
        }
        return res;
    }

    public static void main(String[] args)
    {
        int[] arr = { 3, 1, 4, 4, 5, 2, 6, 1 };
        int k = 2;
        ArrayList<Integer> res = topKFreq(arr, k);
        Collections.reverse(res);
        for (int i = 0; i < res.size(); i++)
            System.out.print(res.get(i) + " ");
    }
}
Python
import heapq

def topKFreq(arr, k):
    
    # Dictionary to store frequency of each element
    mp = {}
    for val in arr:
        mp[val] = mp.get(val, 0) + 1

    # Min-heap to keep track of top k frequent elements
    # Each element in heap: [frequency, element]
    pq = []

    for key, freq in mp.items():

        # Push the current element and its frequency into heap
        heapq.heappush(pq, [freq, key])

        # If heap size exceeds k,
        # remove the element with smallest frequency
        if len(pq) > k:
            heapq.heappop(pq)

    res = []

    # Extract elements from heap in descending frequency order
    temp = [0] * len(pq)
    index = len(pq) - 1
    while pq:
        temp[index] = heapq.heappop(pq)[1]
        index -= 1
    for val in temp:
        res.append(val)

    return res

if __name__ == "__main__":
    arr = [3, 1, 4, 4, 5, 2, 6, 1]
    k = 2
    res = topKFreq(arr, k)
    for val in res:
        print(val, end=" ")
C#
using System;
using System.Collections.Generic;

// Custom MinHeap class
class MinHeap {
    private List<(int freq, int val)> heap = new List<(int, int)>();

    private void Swap(int i, int j) {
        var temp = heap[i];
        heap[i] = heap[j];
        heap[j] = temp;
    }

    private void HeapifyUp(int index) {
        while (index > 0) {
            int parent = (index - 1) / 2;
            if (Compare(heap[index], heap[parent]) < 0) {
                Swap(index, parent);
                index = parent;
            } else break;
        }
    }

    private void HeapifyDown(int index) {
        int n = heap.Count;
        while (true) {
            int left = 2 * index + 1;
            int right = 2 * index + 2;
            int smallest = index;

            if (left < n && Compare(heap[left], heap[smallest]) < 0)
                smallest = left;
            if (right < n && Compare(heap[right], heap[smallest]) < 0)
                smallest = right;

            if (smallest != index) {
                Swap(index, smallest);
                index = smallest;
            } else break;
        }
    }

    // Compare by frequency, then by value
    private int Compare((int freq, int val) a, (int freq, int val) b) {
        if (a.freq != b.freq) return a.freq - b.freq;
        return a.val - b.val;
    }

    public void Add(int val, int freq) {
        heap.Add((freq, val));
        HeapifyUp(heap.Count - 1);
    }

    public (int freq, int val) Pop() {
        var top = heap[0];
        heap[0] = heap[heap.Count - 1];
        heap.RemoveAt(heap.Count - 1);
        if (heap.Count > 0) HeapifyDown(0);
        return top;
    }

    public (int freq, int val) Peek() {
        return heap[0];
    }

    public int Count() {
        return heap.Count;
    }
}

class GFG {

    static List<int> topKFreq(int[] arr, int k) {

         // Dictionary to store frequency of each element
        Dictionary<int, int> mp = new Dictionary<int, int>();
        foreach (int val in arr) {
            if (mp.ContainsKey(val))
                mp[val]++;
            else
                mp[val] = 1;
        }

        // Min-heap to keep track of top k frequent elements
    // [frequency, element]
        MinHeap pq = new MinHeap();
        foreach (var entry in mp) {
            
              // Push the current element 
        // and its frequency into heap
            pq.Add(entry.Key, entry.Value);
         
         
          // If heap size exceeds k, remove 
        // the element with smallest frequency
            if (pq.Count() > k)
                pq.Pop();
        }



        // Extract elements from heap 
        // in descending frequency order
        List<int> res = new List<int>();
        while (pq.Count() > 0)
            res.Insert(0, pq.Pop().val);

        return res;
    }

    static void Main() {
        int[] arr = {3, 1, 4, 4, 5, 2, 6, 1};
        int k = 2;
        List<int> res = topKFreq(arr, k);

        foreach (int val in res)
            Console.Write(val + " ");
    }
}
JavaScript
// Min-Heap class
class MinHeap {
    constructor() {
        this.heap = [];
    }

    push(item) {
        this.heap.push(item);
        this._heapifyUp();
    }

    pop() {
        if (this.size() === 0) return null;
        const top = this.heap[0];
        const end = this.heap.pop();
        if (this.size() > 0) {
            this.heap[0] = end;
            this._heapifyDown();
        }
        return top;
    }

    size() {
        return this.heap.length;
    }

    _heapifyUp() {
        let idx = this.heap.length - 1;
        while (idx > 0) {
            let parent = Math.floor((idx - 1) / 2);
            
            // Compare frequency first, if equal compare element value
            if (this._compare(this.heap[idx], this.heap[parent]) >= 0) break;
            [this.heap[idx], this.heap[parent]] = [this.heap[parent], this.heap[idx]];
            idx = parent;
        }
    }

    _heapifyDown() {
        let idx = 0;
        const n = this.heap.length;
        while (true) {
            let left = 2 * idx + 1;
            let right = 2 * idx + 2;
            let smallest = idx;

            if (left < n && this._compare(this.heap[left], this.heap[smallest]) < 0) smallest = left;
            if (right < n && this._compare(this.heap[right], this.heap[smallest]) < 0) smallest = right;

            if (smallest === idx) break;

            [this.heap[idx], this.heap[smallest]] = [this.heap[smallest], this.heap[idx]];
            idx = smallest;
        }
    }

    top() {
        return this.heap[0];
    }

    // Comparison: first by frequency, then by element value
    _compare(a, b) {
        if (a[0] !== b[0]) return a[0] - b[0]; 
        return a[1] - b[1];
    }
}

function topKFreq(arr, k) {

    // Map to store frequency of each element
    let mp = new Map();
    for (let val of arr) {
        mp.set(val, (mp.get(val) || 0) + 1);
    }

    // Min-heap to keep track of top k frequent elements
    // [frequency, element]
    let pq = new MinHeap();

    for (let [key, freq] of mp.entries()) {
        
        // Push the current element 
        // and its frequency into heap
        pq.push([freq, key]);

        // If heap size exceeds k, remove 
        // the element with smallest frequency
        if (pq.size() > k)
            pq.pop();
    }

    let res = [];

    // Extract elements from heap 
    // in descending frequency order
    let temp = [];
    while (pq.size() > 0) temp.push(pq.pop());
    for (let i = temp.length - 1; i >= 0; i--) res.push(temp[i][1]);

    return res;
}

// Driver code
let arr = [3, 1, 4, 4, 5, 2, 6, 1];
let k = 2;
let res = topKFreq(arr, k);
console.log(...res); 

Output
4 1 

Time Complexity: O(n + k*log k ), where n is the size of array.
Auxiliary Space: O(d), where d is the count of distinct elements in the array. 

[Expected Approach 2] Using Counting sort - O(n log n) Time and O(n) Space

The idea is to utilise more space to improve the time complexity, we store the elements based on their frequencies. We can use the frequency of each element as index of 2D array, where each index represents a list of elements of specific frequency. By doing this, we reduce the need for complex sorting operations. Instead, we can efficiently traverse the buckets from highest frequency to lowest and collect the top k most frequent elements.

C++
#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>
using namespace std;

vector<int> topKFreq(vector<int>& arr, int k) {
    
    // Count frequency of each element
    unordered_map<int, int> freq;
    for (int num : arr) {
       freq[num]++;
    }
    
    //Find the maximum frequency
    int maxFreq = 0;
    for (pair<int,int> entry : freq) {
        maxFreq = max(maxFreq, entry.second);
    }
    
    // Create buckets based on frequencies
     // Each bucket index represents frequency
    vector<vector<int>> buckets(maxFreq + 1); 
    for (pair<int,int> entry : freq) {
        buckets[entry.second].push_back(entry.first);
    }
    
    // Collect top k frequent elements
    vector<int> res;
    for (int i = maxFreq; i >= 1; --i) {
        
        sort(buckets[i].begin(), buckets[i].end(), 
                                    greater<int>());
        
        for (int num : buckets[i]) {
            res.push_back(num);
            if (res.size() == k) {
                return res;
            }
        }
    }
    
    return res;
}

int main() {
    vector<int> arr = { 3, 1, 4, 4, 5, 2, 6, 1 };
    int k = 2;
    
    vector<int> res = topKFreq(arr, k);
    
    for (int num : res) 
        cout << num << " ";
    
    return 0;
}
Java
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.Collections;

class GFG {

    static ArrayList<Integer> topKFreq(int[] arr, int k) {

        // Count frequency of each element
        HashMap<Integer, Integer> freq = new HashMap<>();
        for (int num : arr) {
            freq.put(num, freq.getOrDefault(num, 0) + 1);
        }

        // Find the maximum frequency
        int maxFreq = 0;
        for (Map.Entry<Integer, Integer> entry : freq.entrySet()) {
            maxFreq = Math.max(maxFreq, entry.getValue());
        }

        // Create buckets based on frequencies
        // Each bucket index represents frequency
        ArrayList<ArrayList<Integer>> buckets = new ArrayList<>();
        for (int i = 0; i <= maxFreq; i++) {
            buckets.add(new ArrayList<>());
        }

        for (Map.Entry<Integer, Integer> entry : freq.entrySet()) {
            buckets.get(entry.getValue()).add(entry.getKey());
        }

        // Collect top k frequent elements
        ArrayList<Integer> res = new ArrayList<>();
        for (int i = maxFreq; i >= 1; --i) {
            Collections.sort(buckets.get(i), Collections.reverseOrder());

            for (int num : buckets.get(i)) {
                res.add(num);
                if (res.size() == k) {
                    return res;
                }
            }
        }

        return res;
    }

    public static void main(String[] args) {
        int[] arr = {3, 1, 4, 4, 5, 2, 6, 1};
        int k = 2;

        ArrayList<Integer> res = topKFreq(arr, k);

        for (int num : res)
            System.out.print(num + " ");
    }
}
Python
def topKFreq(arr, k):
    
    # Count frequency of each element
    freq = {}
    for num in arr:
        freq[num] = freq.get(num, 0) + 1

    # Find the maximum frequency
    maxFreq = max(freq.values())

    # Create buckets based on frequencies
    # Each bucket index represents frequency
    buckets = [[] for _ in range(maxFreq + 1)]
    for num, count in freq.items():
        buckets[count].append(num)

    # Collect top k frequent elements
    res = []
    for i in range(maxFreq, 0, -1):
        buckets[i].sort(reverse=True)

        for num in buckets[i]:
            res.append(num)
            if len(res) == k:
                return res

    return res

if __name__ == "__main__":
    arr = [3, 1, 4, 4, 5, 2, 6, 1]
    k = 2
    res = topKFreq(arr, k)
    
    print(" ".join(map(str, res)))
C#
using System;
using System.Collections.Generic;
using System.Linq;

class GFG {
    static List<int> topKFreq(int[] arr, int k) {

        // Count frequency of each element
        Dictionary<int, int> freq = new Dictionary<int, int>();
        foreach (int num in arr) {
            if (!freq.ContainsKey(num))
                freq[num] = 0;
            freq[num]++;
        }

        // Find the maximum frequency
        int maxFreq = freq.Values.Max();

        // Create buckets based on frequencies
        // Each bucket index represents frequency
        List<List<int>> buckets = new List<List<int>>();
        for (int i = 0; i <= maxFreq; i++)
            buckets.Add(new List<int>());

        foreach (var entry in freq)
            buckets[entry.Value].Add(entry.Key);

        // Collect top k frequent elements
        List<int> res = new List<int>();
        for (int i = maxFreq; i >= 1; --i) {
            buckets[i].Sort((a, b) => b.CompareTo(a));

            foreach (int num in buckets[i]) {
                res.Add(num);
                if (res.Count == k)
                    return res;
            }
        }

        return res;
    }

    public static void Main() {
        int[] arr = {3, 1, 4, 4, 5, 2, 6, 1};
        int k = 2;

        List<int> res = topKFreq(arr, k);

        foreach (int num in res)
            Console.Write(num + " ");
    }
}
JavaScript
function topKFreq(arr, k) {

    // Count frequency of each element
    let freq = new Map();
    for (let num of arr) {
        freq.set(num, (freq.get(num) || 0) + 1);
    }

    // Find the maximum frequency
    let maxFreq = Math.max(...freq.values());

    // Create buckets based on frequencies
    // Each bucket index represents frequency
    let buckets = Array.from({ length: maxFreq + 1 }, () => []);

    for (let [num, count] of freq.entries()) {
        buckets[count].push(num);
    }

    // Collect top k frequent elements
    let res = [];
    for (let i = maxFreq; i >= 1; --i) {
        buckets[i].sort((a, b) => b - a);

        for (let num of buckets[i]) {
            res.push(num);
            if (res.length === k) {
                return res;
            }
        }
    }

    return res;
}

// Driver code
let arr = [3, 1, 4, 4, 5, 2, 6, 1];
let k = 2;
let res = topKFreq(arr, k);

console.log(res.join(" "));

Output
4 1 

[Alternate Approach] Using Quick Select

The idea is to use QuickSelect to find the top k frequent elements by partitioning the array based on element frequency. We pick a pivot and place all elements with higher frequency to its left and lower frequency to its right, putting the pivot in its correct position. We then recursively focus only on the part that can contain the k-th most frequent element.

C++
#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>

using namespace std;

// Partition function for quickselect
int partition(int left, int right, int pivotIdx,
              vector<int> &distinct, unordered_map<int, int> &mp) {
                  
    // Frequency of pivot element
    int pivotFreq = mp[distinct[pivotIdx]]; 
    
     // Pivot element value
    int pivotVal = distinct[pivotIdx];     

    swap(distinct[pivotIdx], distinct[right]);

    int j = left;
    for (int i = left; i < right; i++) {
        
        // Place elements with smaller frequency OR smaller value first
        // So top-k (highest freq, largest value) end up at the end
        if (mp[distinct[i]] < pivotFreq || 
            (mp[distinct[i]] == pivotFreq && distinct[i] < pivotVal)) {
            swap(distinct[i], distinct[j]);
            j++;
        }
    }

    swap(distinct[j], distinct[right]); 
    return j;
}

// Quickselect function to partially sort the array
void quickselect(int left, int right, int k, 
                 vector<int> &distinct, unordered_map<int, int> &mp) {

    if (left >= right) return;

    int pivotIdx = left + rand() % (right - left + 1); 
    pivotIdx = partition(left, right, pivotIdx, distinct, mp);

    if (pivotIdx == k) return;
    else if (pivotIdx > k)
        quickselect(left, pivotIdx - 1, k, distinct, mp);
    else
        quickselect(pivotIdx + 1, right, k, distinct, mp);
}

// Function to find top k frequent elements
vector<int> topKFreq(vector<int>& arr, int k) {
    vector<int> distinct;
    unordered_map<int, int> mp;

    // Count frequency of each element
    for (int val : arr) mp[val]++;

    // Store unique elements in distinct array
    for (auto &p : mp) distinct.push_back(p.first);

    int n = distinct.size();

    // Quickselect to move top k frequent elements to the end
    quickselect(0, n - 1, n - k, distinct, mp);

    // Sort top k elements by frequency descending, then value descending
    sort(distinct.begin() + n - k, distinct.end(), [&](int a, int b){
        if(mp[a] != mp[b]) return mp[a] > mp[b]; 
        return a > b;
    });

    // Collect top k frequent elements
    vector<int> res;
    for (int i = n - k; i < n; i++) res.push_back(distinct[i]);

    return res;
}

int main() {
    vector<int> arr{ 3, 1, 4, 4, 5, 2, 6, 1 };
    int k = 2;

    vector<int> res = topKFreq(arr, k);

    for (int val: res) 
        cout << val << " ";

    return 0;
}
Java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Random;
import java.util.Arrays;
import java.util.Collections;

class GFG {

    // Partition function for quickselect
    int partition(int left, int right, int pivotIdx,
                  Integer[] distinct, Map<Integer, Integer> mp) {

        // Frequency of pivot element
        int pivotFreq = mp.get(distinct[pivotIdx]);

        // Pivot element value
        int pivotVal = distinct[pivotIdx];

        int temp = distinct[pivotIdx];
        distinct[pivotIdx] = distinct[right];
        distinct[right] = temp;

        int j = left;
        for (int i = left; i < right; i++) {

            // Place elements with smaller frequency OR smaller value first
            // So top-k (highest freq, largest value) end up at the end
            if (mp.get(distinct[i]) < pivotFreq ||
                (mp.get(distinct[i]) == pivotFreq && distinct[i] < pivotVal)) {
                int t = distinct[i];
                distinct[i] = distinct[j];
                distinct[j] = t;
                j++;
            }
        }

        temp = distinct[j];
        distinct[j] = distinct[right];
        distinct[right] = temp;

        return j;
    }

    // Quickselect function to partially sort the array
    void quickselect(int left, int right, int k,
                     Integer[] distinct, Map<Integer, Integer> mp) {

        if (left >= right) return;

        int pivotIdx = left + new Random().nextInt(right - left + 1);
        pivotIdx = partition(left, right, pivotIdx, distinct, mp);

        if (pivotIdx == k) return;
        else if (pivotIdx > k)
            quickselect(left, pivotIdx - 1, k, distinct, mp);
        else
            quickselect(pivotIdx + 1, right, k, distinct, mp);
    }

    // Function to find top k frequent elements
    ArrayList<Integer> topKFreq(int[] arr, int k) {
        Set<Integer> set = new HashSet<>();
        Map<Integer, Integer> mp = new HashMap<>();

        // Count frequency of each element
        for (int val : arr) {
            mp.put(val, mp.getOrDefault(val, 0) + 1);
            set.add(val);
        }

        // Convert set to array
        Integer[] distinct = set.toArray(new Integer[0]);
        int n = distinct.length;

        // Quickselect to move top k frequent elements to the end
        quickselect(0, n - 1, n - k, distinct, mp);

        // Sort top k elements by frequency descending, then value descending
        Arrays.sort(distinct, n - k, n, (a, b) -> {
            if (!mp.get(a).equals(mp.get(b))) return mp.get(b) - mp.get(a);
            return b - a;
        });

        // Collect top k frequent elements
        ArrayList<Integer> res = new ArrayList<>();
        for (int i = n - k; i < n; i++) res.add(distinct[i]);

        return res;
    }

    public static void main(String[] args) {
        GFG sol = new GFG();
        int[] arr = {3, 1, 4, 4, 5, 2, 6, 1};
        int k = 2;

        ArrayList<Integer> res = sol.topKFreq(arr, k);

        for (int val : res)
            System.out.print(val + " ");
    }
}
Python
import random

# Partition function for quickselect
def partition(left, right, pivotIdx, distinct, freq_map):
    pivotFreq = freq_map[distinct[pivotIdx]]
    pivotVal = distinct[pivotIdx]

    distinct[pivotIdx], distinct[right] = distinct[right], distinct[pivotIdx]

    j = left
    for i in range(left, right):
        
        # Place elements with smaller frequency OR smaller value first
        # So top-k (highest freq, largest value) end up at the end
        if freq_map[distinct[i]] < pivotFreq or (freq_map[distinct[i]] == pivotFreq and distinct[i] < pivotVal):
            distinct[i], distinct[j] = distinct[j], distinct[i]
            j += 1

    distinct[j], distinct[right] = distinct[right], distinct[j]
    return j

# Quickselect function to partially sort the array
def quickselect(left, right, k, distinct, freq_map):
    if left >= right:
        return

    pivotIdx = left + random.randint(0, right - left)
    pivotIdx = partition(left, right, pivotIdx, distinct, freq_map)

    if pivotIdx == k:
        return
    elif pivotIdx > k:
        quickselect(left, pivotIdx - 1, k, distinct, freq_map)
    else:
        quickselect(pivotIdx + 1, right, k, distinct, freq_map)

# Function to find top k frequent elements
def topKFreq(arr, k):
    freq_map = {}
    distinct_set = set()

    # Count frequency of each element
    for val in arr:
        freq_map[val] = freq_map.get(val, 0) + 1
        distinct_set.add(val)

    distinct = list(distinct_set)
    n = len(distinct)

    # Quickselect to move top k frequent elements to the end
    quickselect(0, n - 1, n - k, distinct, freq_map)

    # Sort top k elements by frequency descending, then value descending
    top_k = distinct[n - k:]
    top_k.sort(key=lambda x: (freq_map[x], x), reverse=True)

    return top_k

if __name__ == "__main__":
    arr = [3, 1, 4, 4, 5, 2, 6, 1]
    k = 2
    res = topKFreq(arr, k)
    print(" ".join(str(x) for x in res))
C#
using System;
using System.Collections.Generic;

class GFG {
    
    // Partition function for quickselect
    int partition(int left, int right, int pivotIdx, 
                int[] distinct, Dictionary<int, int> freqMap) {
        int pivotFreq = freqMap[distinct[pivotIdx]];
        int pivotVal = distinct[pivotIdx];

        // Swap pivot with right
        int temp = distinct[pivotIdx];
        distinct[pivotIdx] = distinct[right];
        distinct[right] = temp;

        int j = left;
        for (int i = left; i < right; i++)
        {
            // Place elements with smaller freq OR smaller value first
            // So top-k (highest freq, largest value) end up at the end
            if (freqMap[distinct[i]] < pivotFreq ||
                    (freqMap[distinct[i]] == pivotFreq && distinct[i] < pivotVal)) {
                temp = distinct[i];
                distinct[i] = distinct[j];
                distinct[j] = temp;
                j++;
            }
        }

        temp = distinct[j];
        distinct[j] = distinct[right];
        distinct[right] = temp;

        return j;
    }

    // Quickselect function to partially sort the array
    void quickselect(int left, int right, int k, int[] distinct,
                                        Dictionary<int, int> freqMap) {
        if (left >= right) return;

        Random rand = new Random();
        int pivotIdx = left + rand.Next(right - left + 1);

        pivotIdx = partition(left, right, pivotIdx, distinct, freqMap);

        if (pivotIdx == k) return;
        else if (pivotIdx > k)
            quickselect(left, pivotIdx - 1, k, distinct, freqMap);
        else
            quickselect(pivotIdx + 1, right, k, distinct, freqMap);
    }

    // Function to find top k frequent elements
    public List<int> topKFreq(int[] arr, int k) {
        Dictionary<int, int> freqMap = new Dictionary<int, int>();
        HashSet<int> distinctSet = new HashSet<int>();

        // Count frequency of each element
        foreach (int val in arr)
        {
            if (!freqMap.ContainsKey(val)) freqMap[val] = 0;
            freqMap[val]++;
            distinctSet.Add(val);
        }

        int n = distinctSet.Count;
        int[] distinct = new int[n];
        distinctSet.CopyTo(distinct);

        // Quickselect to move top k frequent elements to the end
        quickselect(0, n - 1, n - k, distinct, freqMap);

        // Sort top k elements by frequency descending, then value descending
        Array.Sort(distinct, n - k, k, Comparer<int>.Create((a, b) =>
        {
            if (freqMap[a] != freqMap[b]) return freqMap[b] - freqMap[a];
            return b - a;
        }));

        // Collect top k frequent elements
        List<int> res = new List<int>();
        for (int i = n - k; i < n; i++)
            res.Add(distinct[i]);

        return res;
    }

    static void Main()
    {
        int[] arr = { 3, 1, 4, 4, 5, 2, 6, 1 };
        int k = 2;
    
        GFG obj = new GFG();
        List<int> res = obj.topKFreq(arr, k);
    
        Console.WriteLine(string.Join(" ", res));
    }
}
JavaScript
function partition(left, right, pivotIdx, distinct, freqMap) {
    let pivotFreq = freqMap.get(distinct[pivotIdx]);
    let pivotVal = distinct[pivotIdx];

    // Swap pivot with right
    [distinct[pivotIdx], distinct[right]] = [distinct[right], distinct[pivotIdx]];

    let j = left;
    for (let i = left; i < right; i++) {
        
        // Place elements with smaller freq OR smaller value first
        // So top-k (highest freq, largest value) end up at the end
        if (freqMap.get(distinct[i]) < pivotFreq ||
            (freqMap.get(distinct[i]) === pivotFreq && distinct[i] < pivotVal)) {
            [distinct[i], distinct[j]] = [distinct[j], distinct[i]];
            j++;
        }
    }

    [distinct[j], distinct[right]] = [distinct[right], distinct[j]];
    return j;
}

function quickselect(left, right, k, distinct, freqMap) {
    if (left >= right) return;

    let pivotIdx = left + Math.floor(Math.random() * (right - left + 1));
    pivotIdx = partition(left, right, pivotIdx, distinct, freqMap);

    if (pivotIdx === k) return;
    else if (pivotIdx > k) quickselect(left, pivotIdx - 1, k, distinct, freqMap);
    else quickselect(pivotIdx + 1, right, k, distinct, freqMap);
}

function topKFreq(arr, k) {
    let freqMap = new Map();
    let distinctSet = new Set();

    // Count frequency of each element
    for (let val of arr) {
        freqMap.set(val, (freqMap.get(val) || 0) + 1);
        distinctSet.add(val);
    }

    let distinct = Array.from(distinctSet);
    let n = distinct.length;

    // Quickselect to move top k frequent elements to the end
    quickselect(0, n - 1, n - k, distinct, freqMap);

    // Sort top k elements by frequency descending, then value descending
    let topK = distinct.slice(n - k);
    topK.sort((a, b) => {
        if (freqMap.get(a) !== freqMap.get(b)) return freqMap.get(b) - freqMap.get(a);
        return b - a;
    });

    return topK;
}

// Driver Code
let arr = [3, 1, 4, 4, 5, 2, 6, 1];
let k = 2;
let res = topKFreq(arr, k);

console.log(res.join(" "));

Output
4 1 

Time complexity:  O(n + d^2), the QuickSelect algorithm takes O(d log d) time on average and works faster than other O(d log d) algorithms in practice.
Auxiliary Space: O(n)

Comment