本文正在参与掘金团队号上线活动,点击 查看大厂春招职位
一、题目描述:
本题来自 LeetCode 347. 前 k 个高频元素。
二、思路分析:
这道题的题面非常简单,考察的主要是数据结构的使用,我就不做过多的分析了,如果熟悉 STL 中哈希表和优先队列的用法,这道题想必没什么问题。
-
要找到”前 K 个高频元素“,我们首先就需要统计每个数字出现的次数,这个过程使用哈希表是不二选择,当然你也可以通过离散化来处理,不过对这道题来说离散化不是必要的。这里有一个 trick 可以注意一下,在 C++ 中
map和unordered_map所存元素的初始值是0,所以可以直接对表中不存在的元素进行自增操作。 -
统计好元素出现的次数后下一步就是排序,这里我们选用了优先队列来实现,STL 的优先队列默认是最大堆刚好满足题目的要求,而且我们也不必定义专门的比较函数,可以直接使用内置的
pair作为优先队列存储的元素类型,因为pair默认的比较函数会先比较first的值再比较second的值,就像字符串的比较大小一样,如果有题目要存储的元素类型包含的值不止两个,我们还可以使用vector替代。 -
其实这道题使用快速排序的思想是更好的选择,在每次划分数组的时候根据所选元素最后所处位置和 进行比较而选择左边或右边继续递归,最终只保证前 个元素是数组中最小的而不是完全有序。这种做法的平均时间复杂度是 ,但在最坏情况会退化到 ,所以在这道题里使用优先队列 这种偷懒的做法也不是不行。
三、AC 代码:
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
// 使用哈希表记录统计每种数出现的次数
unordered_map<int, int> mp;
for (int num : nums) {
++mp[num];
}
// 每个 pair 的 first 存放的是数出现的次数,second 则是数的值
priority_queue<pair<int, int>> pq;
for (auto &[val, cnt] : mp) {
pq.emplace(cnt, val);
}
vector<int> ans;
for (int i = 0; i < k; ++i) {
ans.push_back(pq.top().second);
pq.pop();
}
return ans;
}
};
四、总结:
这道题解法可以说十分朴素了,但就像我之前提到的,这道题主要考察的是数据结构的使用,俗话说得好:“没有脱离数据结构的算法”。大家在学习算法的时候也不要忽视基本数据结构的使用,它们是一切算法的基础。这道题用 STL 来写有点像耍赖,觉得过于简单的话你也可以用快排思想来写,但那就是另一个故事了。