题目:
给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。
返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序 排序。
示例 1:
输入: words = ["i", "love", "leetcode", "i", "love", "coding"], k = 2
输出: ["i", "love"]
解析: "i" 和 "love" 为出现次数最多的两个单词,均为2次。
注意,按字母顺序 "i" 在 "love" 之前。
示例 2:
输入: ["the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"], k = 4
输出: ["the", "is", "sunny", "day"]
解析: "the", "is", "sunny" 和 "day" 是出现次数最多的四个单词,
出现次数依次为 4, 3, 2 和 1 次。
注意:
1 <= words.length <= 500
1 <= words[i] <= 10
words[i] 由小写英文字母组成。
k 的取值范围是 [1, 不同 words[i] 的数量]
思路一:暴力解法,这道题如果没用时间限制,暴力解法很简单的。
思路二:哈希表+排序;先将words数组的单词按照首字母的字典顺序排序。因为题中说的如果两个单词出现频率相同,优先首字母在前的单词。定义vet——string数组,记录words数组的一次单词,用来后面的按照出现频率排序要求。
定义unordered_map数组,记录每个单词出现的次数,将每个单词出现的频率存放在path数组中(无顺序要求)。对path数组的元素进行排序,找到前K个元素。再一次对存放string的数组遍历,大于path【k】的存放在之前定义好的变量数组v中(一定要按照从大到小的顺序)。
完整代码:
- class Solution {
- public:
- vector
topKFrequent(vector& words, int k) { - sort(words.begin(),words.end());
- vector
vet; - vet.assign(words.begin(),words.end());
- vet.erase(unique(vet.begin(),vet.end()),vet.end());
- unordered_map
int>mp; - vector<int>path;
- vector
v; - for(int i=0;i
size();i++) - {
- auto it=mp.find(words[i]);
- if(it==mp.end())
- {
- mp[words[i]]=1;
- }
- else
- {
- mp[words[i]]++;
- }
- }
- for(int i=0;i
size();i++) - {
- path.push_back(mp[vet[i]]);
- }
- sort(path.begin(),path.end());
- reverse(path.begin(),path.end());
- int x=path[0];
- int len=vet.size();
- int pos=0;
- for(int i=0;i
- {
- if(mp[vet[i]]==path[0])
- {
- v.push_back(vet[i]);
- path.erase(path.begin());
- vet.erase(vet.begin()+i);
- i=-1;
- pos=pos+1;
- }
- if(pos==k)
- {
- break;
- }
- }
- return v;
- }
- };
path【i】是从大到小排序的,如果遍历到path【0】,则将vet【i】存放在string数组v中;path【0】、vet【i】将被移除;然后i=-1是重新从数组的起始开始遍历。
ps:一直是path【0】的原因是每次将path首元素删除后,接着就会有下一个元素补上去,所以一直是path【0】。
当计数元素pos==k时,说明已经达到题中给的条件,直接结束for()语句。