# Top K Frequent Elements
###### tags: `Medium`
>question : https://leetcode.com/explore/interview/card/top-interview-questions-medium/110/sorting-and-searching/799/
>reference :
>related problem :
## My Solution
先做統計,再去找最大的 k 個數
```java=
class Solution {
public int[] topKFrequent(int[] nums, int k) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
int[] ans = new int[k];
for(int i = 0; i < nums.length; i++) {
map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);
}
for(int j = 0; j < k; j++) {
int max = 0;
int max_num = 0;
for(Integer num : map.keySet()) {
if(map.get(num) > max) {
max = map.get(num);
max_num = num;
}
}
ans[j] = max_num;
map.remove(max_num);
}
return ans;
}
}
```
## Other Solution
### Priorty Queue
```java=
class Solution {
public int[] topKFrequent(int[] nums, int k) {
// O(1) time
if (k == nums.length) {
return nums;
}
// 1. build hash map : character and how often it appears
// O(N) time
Map<Integer, Integer> count = new HashMap();
for (int n: nums) {
count.put(n, count.getOrDefault(n, 0) + 1);
}
// init heap 'the less frequent element first'
Queue<Integer> heap = new PriorityQueue<>(
(n1, n2) -> count.get(n1) - count.get(n2));
// 2. keep k top frequent elements in the heap
// O(N log k) < O(N log N) time
for (int n: count.keySet()) {
heap.add(n);
if (heap.size() > k) heap.poll();
}
// 3. build an output array
// O(k log k) time
int[] top = new int[k];
for(int i = k - 1; i >= 0; --i) {
top[i] = heap.poll();
}
return top;
}
}
```
### Hoare's selection algorithm
```java=
class Solution {
int[] unique;
Map<Integer, Integer> count;
public void swap(int a, int b) {
int tmp = unique[a];
unique[a] = unique[b];
unique[b] = tmp;
}
public int partition(int left, int right, int pivot_index) {
int pivot_frequency = count.get(unique[pivot_index]);
// 1. move pivot to end
swap(pivot_index, right);
int store_index = left;
// 2. move all less frequent elements to the left
for (int i = left; i <= right; i++) {
if (count.get(unique[i]) < pivot_frequency) {
swap(store_index, i);
store_index++;
}
}
// 3. move pivot to its final place
swap(store_index, right);
return store_index;
}
public void quickselect(int left, int right, int k_smallest) {
/*
Sort a list within left..right till kth less frequent element
takes its place.
*/
// base case: the list contains only one element
if (left == right) return;
// select a random pivot_index
Random random_num = new Random();
int pivot_index = left + random_num.nextInt(right - left);
// find the pivot position in a sorted list
pivot_index = partition(left, right, pivot_index);
// if the pivot is in its final sorted position
if (k_smallest == pivot_index) {
return;
} else if (k_smallest < pivot_index) {
// go left
quickselect(left, pivot_index - 1, k_smallest);
} else {
// go right
quickselect(pivot_index + 1, right, k_smallest);
}
}
public int[] topKFrequent(int[] nums, int k) {
// build hash map : character and how often it appears
count = new HashMap();
for (int num: nums) {
count.put(num, count.getOrDefault(num, 0) + 1);
}
// array of unique elements
int n = count.size();
unique = new int[n];
int i = 0;
for (int num: count.keySet()) {
unique[i] = num;
i++;
}
// kth top frequent element is (n - k)th less frequent.
// Do a partial sort: from less frequent to the most frequent, till
// (n - k)th less frequent element takes its place (n - k) in a sorted array.
// All element on the left are less frequent.
// All the elements on the right are more frequent.
quickselect(0, n - 1, n - k);
// Return top k frequent elements
return Arrays.copyOfRange(unique, n - k, n);
}
}
```