C++实现LeetCode(692.前K个高频词)
[LeetCode] 692.Top K Frequent Words 前K个高频词
Given a non-empty list of words, return the k most frequent elements.
Your answer should be sorted by frequency from highest to lowest. If two words have the same frequency, then the word with the lower alphabetical order comes first.
Example 1:
Input: ["i", "love", "leetcode", "i", "love", "coding"], k = 2Example 2:
Output: ["i", "love"]
Explanation: "i" and "love" are the two most frequent words.
Note that "i" comes before "love" due to a lower alphabetical order.
Input: ["the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"], k = 4Note:
Output: ["the", "is", "sunny", "day"]
Explanation: "the", "is", "sunny" and "day" are the four most frequent words,
with the number of occurrence being 4, 3, 2 and 1 respectively.
- You may assume k is always valid, 1 ≤ k ≤ number of unique elements.
- Input words contain only lowercase letters.
- Try to solve it in O(n log k) time and O(n) extra space.
- Can you solve it in O(n) time with only O(k) extra space?
解法一:
class Solution {public:vector topKFrequent(vector& words, int k) {vector res(k); unordered_map freq; auto cmp = [](pair& a, pair& b) {return a.second > b.second || (a.second == b.second && a.first < b.first); }; priority_queue, vector>, decltype(cmp) > q(cmp); for (auto word : words) ++freq[word]; for (auto f : freq) {q.push(f); if (q.size() > k) q.pop(); }for (int i = res.size() - 1; i >= 0; --i) {res[i] = q.top().first; q.pop(); }return res; }};
下面这种解法还是一种堆排序的思路,这里我们用map,来建立次数和出现该次数所有单词的集合set之间的映射,这里也利用了set能自动排序的特性,当然我们还是需要首先建立每个单词和其出现次数的映射,然后将其组成pair放入map种,map是从小到大排序的,这样我们从最后面取pair,就是次数最大的,每次取出一层中所有的单词,如果此时的k大于该层的单词个数,就将整层的单词加入结果res中,否则就取前K个就行了,取完要更更新K值,如果K小于等于0了,就break掉,返回结果res即可,参见代码如下:
解法二:
class Solution {public:vector topKFrequent(vector& words, int k) {vector res; unordered_map freq; mapm; for (string word : words) ++freq[word]; for (auto a : freq) {m[a.second].insert(a.first); }for (auto it = m.rbegin(); it != m.rend(); ++it) {if (k <= 0) break; auto t = it->second; vector v(t.begin(), t.end()); if (k >= t.size()) {res.insert(res.end(), v.begin(), v.end()); } else {res.insert(res.end(), v.begin(), v.begin() + k); }k -= t.size(); }return res; }};
下面这种解法是一种桶排序的思路,我们根据出现次数建立多个bucket,桶的个数不会超过单词的个数,在每个桶中,我们对单词按字符顺序进行排序。我们可以用个数组来表示桶,每一层中放一个集合,利用set的自动排序的功能,使其能按字母顺序排列。我们还是需要首先建立每个单词和其出现次数的映射,然后将其组成pair放入map种,map是从小到大排序的,这样我们倒序遍历所有的桶,这样取pair,就是次数最大的,每次取出一层中所有的单词,如果此时的k大于该层的单词个数,就将整层的单词加入结果res中,否则就取前K个就行了,取完要更更新K值,如果K小于等于0了,就break掉,返回结果res即可,参见代码如下:
解法三:
class Solution {public:vector topKFrequent(vector& words, int k) {vector res; unordered_map freq; vector> v(words.size() + 1, set()); for (string word : words) ++freq[word]; for (auto a : freq) {v[a.second].insert(a.first); }for (int i = v.size() - 1; i >= 0; --i) {if (k <= 0) break; vector t(v[i].begin(), v[i].end()); if (k >= t.size()) {res.insert(res.end(), t.begin(), t.end()); } else {res.insert(res.end(), t.begin(), t.begin() + k); }k -= t.size(); }return res; }};
类似题目:
【C++实现LeetCode(692.前K个高频词)】Top K Frequent Elements
Design Search Autocomplete System
参考资料:
https://discuss.leetcode.com/topic/106861/o-nlog-k-priority-queue-c-code
https://discuss.leetcode.com/topic/106868/clean-heap-based-solution-o-nlogk-time-and-o-n-space-16ms
到此这篇关于C++实现LeetCode(692.前K个高频词)的文章就介绍到这了,更多相关C++实现前K个高频词内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- MybatisPlus使用queryWrapper如何实现复杂查询
- python学习之|python学习之 实现QQ自动发送消息
- 孩子不是实现父母欲望的工具——林哈夫
- opencv|opencv C++模板匹配的简单实现
- Node.js中readline模块实现终端输入
- 【Leetcode/Python】001-Two|【Leetcode/Python】001-Two Sum
- java中如何实现重建二叉树
- leetcode|leetcode 92. 反转链表 II
- 人脸识别|【人脸识别系列】| 实现自动化妆