C++实现LeetCode(692.前K个高频词)

这篇文章主要介绍了C++实现LeetCode(692.前K个高频词),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

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 = 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.

Example 2:

Input: [\”the\”, \”day\”, \”is\”, \”sunny\”, \”the\”, \”the\”, \”the\”, \”sunny\”, \”is\”, \”is\”], k = 4
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.

Note:

  1. You may assume k is always valid, 1 ≤ k ≤ number of unique elements.
  2. Input words contain only lowercase letters.

Follow up:

  1. Try to solve it in O(n log k) time and O(n) extra space.
  2. Can you solve it in O(n) time with only O(k) extra space?

这道题让我们求前K个高频词,跟之前那道题 Top K Frequent Elements 极其类似,换了个数据类型就又是一道新题。唯一的不同就是之前那道题对于出现频率相同的数字,没有顺序要求。而这道题对于出现频率相同的单词,需要按照字母顺序来排。但是解法都一样,还是用最小堆和桶排序的方法。首先来看最小堆的方法,思路是先建立每个单词和其出现次数之间的映射,然后把单词和频率的pair放进最小堆,如果没有相同频率的单词排序要求,我们完全可以让频率当作pair的第一项,这样priority_queue默认是以pair的第一项为key进行从大到小的排序,而当第一项相等时,又会以第二项由大到小进行排序,这样第一项的排序方式就与题目要求的相同频率的单词要按字母顺序排列不相符,当然我们可以在存入结果res时对相同频率的词进行重新排序处理,也可以对priority_queue的排序机制进行自定义,这里我们采用第二种方法,我们自定义排序机制,我们让a.second > b.second,让小频率的词在第一位,然后当a.second == b.second时,我们让a.first < b.first,这是让字母顺序大的排在前面(这里博主需要强调一点的是,priority_queue的排序机制的写法和vector的sort的排序机制的写法正好顺序相反,同样的写法,用在sort里面就是频率小的在前面,不信的话可以自己试一下)。定义好最小堆后,我们首先统计单词的出现频率,然后组成pair排序最小堆之中,我们只保存k个pair,超过了就把队首的pair移除队列,最后我们把单词放入结果res中即可,参见代码如下:

解法一:

class Solution {public:    vector<string> topKFrequent(vector<string>& words, int k) {        vector<string> res(k);        unordered_map<string, int> freq;        auto cmp = [](pair<string, int>& a, pair<string, int>& b) {            return a.second > b.second || (a.second == b.second && a.first < b.first);        };        priority_queue<pair<string, int>, vector<pair<string, int>>, 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<string> topKFrequent(vector<string>& words, int k) {        vector<string> res;        unordered_map<string, int> freq;        map<int, set<string>> m;        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<string> 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<string> topKFrequent(vector<string>& words, int k) {        vector<string> res;        unordered_map<string, int> freq;        vector<set<string>> v(words.size() + 1, set<string>());        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<string> 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;    }};

类似题目:

Top K Frequent Elements

Design Search Autocomplete System

参考资料:

https://www.zzm8.com/d/file/p/20210809181655165379/20210809181655165380

https://www.zzm8.com/d/file/p/20210809181656165403/20210809181656165404

到此这篇关于C++实现LeetCode(692.前K个高频词)的文章就介绍到这了,更多相关C++实现前K个高频词内容请搜索趣讯吧以前的文章或继续浏览下面的相关文章希望大家以后多多支持趣讯吧!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件至 55@qq.com 举报,一经查实,本站将立刻删除。转转请注明出处:https://www.szhjjp.com/n/11361.html

(0)
nan
上一篇 2021-08-09
下一篇 2021-08-09

相关推荐

  • 2021年重庆市教书育人楷模,是他们!

    原标题:2021年重庆市教书育人楷模,是他们!来源:重庆发布9月8日,重庆市教委发布消息,根据教育部教师工作司开展教书育人楷模推选工作安排,市教委组织2021年重庆市教书育人楷模推选活动,结合王红旭、许林盛救人的先进事迹,经自下而上逐级推选

    2021-09-09
    0
  • 塔利班9月11日举行升旗仪式,(到底发生啥了?)

    最近“塔利班9月11日举行升旗仪式”登上了热搜,引起了网友们的关注,相信还有很多人和小编之前一样不了解“塔利班9月11日举行升旗仪式”是啥?怎么回事?为此小编特意在网上整理了关于“塔利班9月11日举行升旗仪式”的内容,方便您了解其相关信息和

    2021-09-12
    0
  • 为什么家里要有大属相?大属相有什么说法

    在风水算命学中,一般大属相的人就是做事比较雷厉风行并且比较强势顽强的人,这类是其实是非常上进并且有野心的,那么为什么家里要有大属相,大属相有什么说法,大家知道有哪些属相是属于大属相吗,那么接下来大家就随趣讯吧小编一起了解看看~

    2021-09-20
    0
  • 小知识:路由器无线中继是什么意思(具体怎么设置)

    摘要:路由器中继常被用在大居室,一个路由器难以完全覆盖宽带网络的环境,因为物理条件的因素分为有线路由中继和无线路由中继。怎么设置中继模式呢?下面我用小米路由器做一下演示。

    2023-05-30
    0
  • 儿媳妇能告不赡养公婆的小姑子吗(媳妇对公婆有哪些义务)

    儿媳妇不能告不赡养公婆的小姑子,原告应该是老人自己。【法律依据】《婚姻法》第二十一条,父母对子女有抚养教育的义务;子女对父母有赡养扶助的义务。父母不履行抚养义务时,未成年的或不能独立生活的子女,有要求父母付给抚养费的权利。子女不履行赡养义务时,无劳动

    2022-01-10
    0
  • 无意中看到女友在京东写的商品评价(男子:我怀疑她入错行了)

    有趣的灵魂万里挑一,不仅体现在日常的聊天沟通中,也可能存在网购的商品评价中。近日,有网友晒出自己女友在京东写的商品评价,直言:我怀疑她入错行了。大家感受下:健力宝饮料下的评论:

    2021-08-23 热点头条
    0

发表回复

登录后才能评论