###### tags: `Leetcode` `medium` `heap` `bucket` `sort` `python` `c++` `Top 100 Liked Questions`
# 347. Top K Frequent Elements
## [題目連結:] https://leetcode.com/problems/top-k-frequent-elements/description/
## 題目:
Given an integer array ```nums``` and an integer ```k```, return the ```k``` most frequent elements. You may return the answer in **any order**.
* k is in the range [1, the number of unique elements in the array].
* It is guaranteed that the answer is unique.
**Follow up:** Your algorithm's time complexity must be better than ```O(n log n)```, where n is the array's size.
**Example 1:**
```
Input: nums = [1,1,1,2,2,3], k = 2
Output: [1,2]
```
**Example 2:**
```
Input: nums = [1], k = 1
Output: [1]
```
## 解題想法:
* 此題為求數組中k個最常出現的數字
* Sol1: O(NlogN)
* 使用hash table+ heap:
* 統計每個數字其出現次數,再存於heap
* python: heapq為min_heap
* c++: priority_queue<>為max_heap
## Python_Sol1: heap
``` python=
from collections import defaultdict
from heapq import heappush, heappop
class Solution(object):
def topKFrequent(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
dic=defaultdict(int)
que=[]
for val in nums:
dic[val]+=1
for key in dic:
heappush(que,(-dic[key],key))
res=[]
for i in range(k):
res.append(heappop(que)[1])
return res
```
## C++_Sol1: heap
``` cpp=
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> dic;
priority_queue<pair<int, int>> que;
for (auto val: nums){
dic[val]+=1;
}
//key: item.first
//val: item.second
for (auto &item: dic){
pair<int,int> tmp(item.second, item.first);
que.push(tmp);
}
vector<int> res;
for (int i=0; i<k; i++){
res.push_back(que.top().second);
que.pop();
}
return res;
}
};
```
* Sol2: **O(N)**
* 使用**Bucket Sort**
* Step1:
* 編號0~len(nums)個箱子 第i個箱子容量為i
* bucket=[ [] for _ in range(len(nums)+1)]
* Step2:
* hash table紀錄每個數字出現次數
* key: 數字
* val: 出現次數
* Step3:
* **對於hash table中每個key,將其val對應至bucket[val]**
* Step4:
* 將bucket中的元素存於res並取出k個
## Python_Sol2: Bucket Sort
``` python=
from collections import defaultdict
from heapq import heappush, heappop
class Solution(object):
def topKFrequent(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
#bucket sort!!! O(n)
dic=defaultdict(int)
#編號0~len(nums)個箱子 第i個箱子容量為i
bucket=[ [] for _ in range(len(nums)+1)]
for val in nums:
dic[val]+=1
for key in dic:
#ex: key為1時 dic[1]=3 所以在bucket[3]放入1這個key
bucket[dic[key]].append(key)
res=[]
for i in range(len(bucket)):
if bucket[i]:
res.extend(bucket[i])
#因為res為由小到大,所以取最後k個
return res[len(res)-k:]
```
## C++_Sol2: Bucket Sort
* 對於bucket:也可以用map< int,vector < int > >查詢較快
``` cpp=
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> dic;
int n=nums.size();
vector<vector<int>> bucket(n+1, vector<int>());
for (auto val: nums){
dic[val]+=1;
}
for (auto& item: dic){
bucket[item.second].push_back(item.first);
}
vector<int> res;
for (int i=n; i>=0; i--){
for (int j=0; j<bucket[i].size(); j++){
res.push_back(bucket[i][j]);
if (res.size()==k)
return res;
}
}
return res;
}
};
```