Given a non-empty array of integers, return the k most frequent elements.
Example 1:
Input: nums = [1,1,1,2,2,3], k = 2
Output: [1,2]
Example 2:
Input: nums = [1], k = 1
Output: [1]
Note:
- You may assume k is always valid, 1 ≤ k≤ number of unique elements.
- Your algorithm's time complexity must be better than O(n log n), where n is the array's size.
Accepted
190.9K
Submissions
352.5K
思路一:
首先使用哈希表,将数字和对应出现次数记录下来;再将对应关系放入vector<pair<int, int>>中,使用自定义的排序函数cmp对vector进行排序,输出前K个结果即可。
注意:类内调用的cmp函数,必须写成静态成员函数,否则无法正常调用;也可将cmp函数放在类外定义,但这样写比较丑。
静态成员函数的设定用以处理静态成员变量,且其内不可使用非静态成员变量,因为非静态成员变量需要构造出一个实例时才会申请内存。
代码一:
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> m;
for (auto i = nums.begin(); i != nums.end(); ++i) {
m[*i]++;
}
vector<pair<int, int>> ans;
for (auto i = m.begin(); i != m.end(); ++i) {
ans.push_back(make_pair(i->first, i->second));
// cout << i->first << ", " << i->second << endl;
}
sort(ans.begin(), ans.end(), cmp);
vector<int> res;
int i = 0;
while (i < k) {
res.push_back(ans[i].first);
++i;
}
return res;
}
static bool cmp(const pair<int, int> &p1, const pair<int, int> &p2) {
return p1.second > p2.second;
}
};
思路二:
首先使用哈希表,将数字和对应出现次数记录下来;再使用优先队列,将对应数据存入priority_queue<pair<int, int>>,则自动完成排序工作(优先队列内部使用最大堆实现),随后弹出队列top数值,重复k次即可。
代码二:
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> m;
for (auto i = nums.begin(); i != nums.end(); ++i) {
m[*i]++;
}
priority_queue<pair<int, int>> ans;
for (auto i = m.begin(); i != m.end(); ++i) {
ans.push(make_pair(i->second, i->first)); // pair (freq, name)
}
vector<int> res;
int i = 0;
while (i < k) {
res.push_back(ans.top().second); // name is second
ans.pop();
++i;
}
return res;
}
};
思路三:
使用木桶排序,将unordered_map记录的值分别放入vector<vector<int>>木桶中,木桶个数为nums中的数字个数(以保证用最少的内存完成所有实例情况),使用倒序的方式输出k次出现次数最多的值即可。
代码三:
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> m;
for (auto i = nums.begin(); i != nums.end(); ++i) {
m[*i]++;
}
vector<vector<int>> buckets(nums.size()+1);
for (auto i = m.begin(); i != m.end(); ++i) {
buckets[i->second].push_back(i->first);
}
vector<int> res;
for (int i = buckets.size()-1; i >= 0; --i) {
for (int j = 0; j < buckets[i].size(); ++j) {
res.push_back(buckets[i][j]);
}
if (res.size() == k) break;
}
return res;
}
};