思路:
1、map存储每个字符串出现的频率
2、采用大顶堆来存储map的entry对象
3、弹出k个元素到二维数res组里返回
描述
给定一个字符串数组,再给定整数k,请返回出现次数前k名的字符串和对应的次数。
返回的答案应该按字符串出现频率由高到低排序。如果不同的字符串有相同出现频率,按字典序排序。对于两个字符串,大小关系取决于两个字符串从左到右第一个不同字符的 ASCII 值的大小关系。
比如"ah1x"小于"ahb",“231”<”32“
字符仅包含数字和字母
[要求]
如果字符串数组长度为N,时间复杂度请达到O(N \log K)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”]]
复制
备注:
10^51≤N≤10
public static String[][] topKstrings (String[] strings, int k) {
// write code here
HashMap<String,Integer> map = new HashMap<>();
int max = -1;
for(int i = 0; i < strings.length; i++){
map.put(strings[i] ,map.getOrDefault(strings[i],0) + 1);
if (max < map.get(strings[i])) max = map.get(strings[i]);
}
Queue<Map.Entry<String,Integer>> q = new PriorityQueue<>((a,b) ->
{
int res = b.getValue() - a.getValue();
return res == 0 ? a.getKey().compareTo(b.getKey()) : res;
});
for(Map.Entry<String,Integer> entry : map.entrySet()){
q.offer(entry);
}
String[][] res = new String[k][2];
int i = 0;
while (k-- > 0){
Map.Entry<String, Integer> poll = q.poll();
res[i][0] = poll.getKey();
res[i][1] = String.valueOf(poll.getValue());
i++;
}
return res;
}