Leetcode 347 前K个高频元素
问题重述
问题重述:
给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2]
示例 2:
输入: nums = [1], k = 1 输出: [1]
思路
可以理解为把数字值放给桶里,然后桶里面有值。比如给的示例1.
存完以后[1, 3], [2, 2], [3, 1];(数字的值作为下标的那种)。
最后将桶进行排序就可以。可以按照second即频数作为下标排序,也就是第一个[1, 3] 说明排序玩的数组buckets[3] = 1.以此类推,所以最后频数最大的就在buckets数组的最后面,最后按照从最大频数向前数,就可以得到前k个合。
具体看代码注释。
最终代码
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> counts;//建立哈希表,见关键值映射到相应位置
//因为我们要考虑到出现频数相同的情况
int max_count = 0;
for (const int & num : nums) {//每一个元素从前往后枚举出来,并用 num 来表示
max_count = max(max_count, ++counts[num]);//下标代表值,数组值代表频数,给的示例1说明counts[1]=3;
}
vector<vector<int>> buckets(max_count + 1);
for (const auto & p : counts) {
buckets[p.second].push_back(p.first);//bucket就是将counts按照频数进行了从小到大相当于桶排序了
//例如给定数组nums为 2 2 2 1 1 3
//那么 counts元素 : [1,2],[2,3],[3,1];数组第二个元素为频数第一个为值
//所以存到buckets 第一个存buckets[2]=1;然后buckets[3]=2;最后buckets[1]=3;
//一直到最后buckets元素: [1,2],[2,1],[3,2];数组的第一个元素为频数,第二个元素为值
}
vector<int> ans;
for (int i = max_count; i >= 0 && ans.size() < k; --i) {
for (const int & num : buckets[i]) {//buckets[i]是指第i行后面第一个元素,也就是指值
ans.push_back(num);
if (ans.size() == k) {
break;
}
}
}
return ans;
}
};