题目
给一非空的单词列表,返回前 k 个出现次数最多的单词。
返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率,按字母顺序排序。
示例 1:
输入: ["i", "love", "leetcode", "i", "love", "coding"], k = 2
输出: ["i", "love"]
解析: "i" 和 "love" 为出现次数最多的两个单词,均为2次。
注意,按字母顺序 "i" 在 "love" 之前。
思路:
- map联合vector。
- map中的key是唯一的,所以相同的单词在遍历结束后只会出现一次。
- 所以map可以对单词列表进行计数。
- 定义一个map的迭代器对数组进行遍历。键值对为<string,int>
- 将map中的元素放进数组。
- 对数组中的元素进行排序,将排序后的前k个单词放进另一个数组。
注意:map本身具有排序功能,但是是根据key值。所以这里根据题目要求设置排序条件。
class Solution {
public:
vector<string> topKFrequent(vector<string>& words, int k)
{
typedef map<string,int> :: iterator CountMapIt;//迭代器
map<string,int> countMap;//定义一个map,其key为字符串,value为个数的键值对
for(auto e : words)
{
countMap[e]++;
}
//排序
vector<CountMapIt> v;
vector<string> m;
CountMapIt it = countMap.begin();
while(it != countMap.end())
{
v.push_back(it);
++it;
}
struct CountMapCompare
{
bool operator()(const CountMapIt& it1, const CountMapIt& it2)
{
if(it1->second == it2->second)
return it1->first < it2->first;
else
return it1->second > it2->second;
}
};
sort(v.begin(), v.end(),CountMapCompare());
for(auto& e : v)
{
m.push_back(e->first);
k--;
if(k == 0)
{
break;
}
}
return m;
}
};
方法2
//map中存储的键值对<string,int>
//map中的key值默认是从小到大的
//在用一个map将第一个map中的键值对颠倒,并使用逆序插入
//前k个字符串入数组
class Solution {
public:
vector<string> topKFrequent(vector<string>& words, int k)
{
typedef map<string,int>:: iterator CountMapIt;
map<string,int> countMap;
for(auto& e : words)
{
countMap[e]++;
}
multimap<int,string,greater<int>> sortMap;//仿函数
for(auto& e : countMap)
{
sortMap.insert(make_pair(e.second,e.first));
}
vector<string> v;
auto rit = sortMap.begin();
while(k--)
{
v.push_back(rit->second);
rit++;
}
return v;
}