LeetCode 347. 前 k 个高频元素:熟悉 STL 容器用法|刷题打卡

310 阅读2分钟

本文正在参与掘金团队号上线活动,点击 查看大厂春招职位

一、题目描述:

本题来自 LeetCode 347. 前 k 个高频元素

image.png

二、思路分析:

这道题的题面非常简单,考察的主要是数据结构的使用,我就不做过多的分析了,如果熟悉 STL 中哈希表和优先队列的用法,这道题想必没什么问题。

  1. 要找到”前 K 个高频元素“,我们首先就需要统计每个数字出现的次数,这个过程使用哈希表是不二选择,当然你也可以通过离散化来处理,不过对这道题来说离散化不是必要的。这里有一个 trick 可以注意一下,在 C++ 中 mapunordered_map 所存元素的初始值是 0,所以可以直接对表中不存在的元素进行自增操作。

  2. 统计好元素出现的次数后下一步就是排序,这里我们选用了优先队列来实现,STL 的优先队列默认是最大堆刚好满足题目的要求,而且我们也不必定义专门的比较函数,可以直接使用内置的 pair 作为优先队列存储的元素类型,因为 pair 默认的比较函数会先比较 first 的值再比较 second 的值,就像字符串的比较大小一样,如果有题目要存储的元素类型包含的值不止两个,我们还可以使用 vector 替代。

  3. 其实这道题使用快速排序的思想是更好的选择,在每次划分数组的时候根据所选元素最后所处位置和 KK 进行比较而选择左边或右边继续递归,最终只保证前 KK 个元素是数组中最小的而不是完全有序。这种做法的平均时间复杂度是 O(n)O(n),但在最坏情况会退化到 O(n2)O(n^2),所以在这道题里使用优先队列 O(nlog(n))O(nlog(n)) 这种偷懒的做法也不是不行。

三、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 来写有点像耍赖,觉得过于简单的话你也可以用快排思想来写,但那就是另一个故事了。