描述
给定一个字符串数组,再给定整数k,请返回出现次数前k名的字符串和对应的次数。
返回的答案应该按字符串出现频率由高到低排序。如果不同的字符串有相同出现频率,按字典序排序。
对于两个字符串,大小关系取决于两个字符串从左到右第一个不同字符的 ASCII 值的大小关系。比如"ah1x"小于"ahb",“231”<”32“
字符仅包含数字和字母
如果字符串数组长度为N,时间复杂度请达到O(NlogK)
示例1
输入:[“a”,“b”,“c”,“b”],2
返回值:[[“b”,“2”],[“a”,“1”]]
说明:
"b"出现了2次,记[“b”,“2”],"a"与"c"各出现1次,但是a字典序在c前面,记[“a”,“1”],最后返回[[“b”,“2”],[“a”,“1”]]
示例2
输入:[“123”,“123”,“231”,“32”],2
返回值:[[“123”,“2”],[“231”,“1”]]
说明:
"123"出现了2次,记[“123”,“2”],"231"与"32"各出现1次,但是"231"字典序在"32"前面,记[“231”,“1”],最后返回[[“123”,“2”],[“231”,“1”]]
示例3
输入:[“abcd”,“abcd”,“abcd”,“pwb2”,“abcd”,“pwb2”,“p12”],3
返回值:[[“abcd”,“4”],[“pwb2”,“2”],[“p12”,“1”]]
- 首先使用hash表对所有的字符串集合计数,之后将strings按照自定义的排序顺序(出现次数不同,次数大的在前面;出现次数相同,字典序小的在前面)进行排序。
- 将strings排好序之后,根据给定的k值筛选前k个元素,因为按照这样的顺序排序,相当于升序排列,是个小根堆。元素个数不够k个,那么直接放进去,如果大于k个就需要将堆顶元素弹出,然后再将该元素放入。
class Solution {
public:
struct Cmp{
bool operator() (pair<string,int> &a,pair<string,int> &b){
if(a.second!=b.second) return a.second>b.second;
return a.first<b.first;
}
};
vector<vector<string> > topKstrings(vector<string>& strings, int k) {
// write code here
unordered_map<string,int> hash;
for(auto c:strings) hash[c]++;
priority_queue<pair<string,int>,vector<pair<string,int>>,Cmp> q;
for(auto c:hash)
{
if(q.size()<k) q.push(c);
else
{
q.push(c);
q.pop();
}
}
// k=min(k,(int)hash.size());
vector<vector<string>> ans(k,vector<string>());
while(!q.empty())
{
--k;
ans[k].push_back(q.top().first);
ans[k].push_back(to_string(q.top().second));
q.pop();
}
return ans;
}
};