题解 | #字符串出现次数的TopK问题#
字符串出现次数的TopK问题
http://www.nowcoder.com/questionTerminal/fd711bdfa0e840b381d7e1b82183b3ee
1.将传入数组放入hashmap中统计出现次数
2.利用优先级队列来建立堆:需要注意的是优先级队列中元素默认以小根堆排序
2.1将map中前k个元素填入优先级队列(默认小根堆)中
2.2.如果map中剩余节点的num大于堆顶节点的num,入堆
3.将建立好的堆从后往前输出K个,即是最大的K个元素ps:由于字母a,b,c..z的ascii值逐渐增大,所以想要字典排序,以a,b为例,即a在前面b在后面,就需要a<b,即a-b<0,后面重写compareTo会用到.
import java.util.*;
public class Solution {
/**
* return topK string
*
* @param strings string字符串一维数组 strings
* @param k int整型 the k
* @return string字符串二维数组
*/
public static String[][] topKstrings(String[] strings, int k) {
if(strings==null || strings.length==0){
return null;
}
// write code here
PriorityQueue<MyNode> heap = new PriorityQueue<MyNode>();
//传入统计后结果map
HashMap<String, Integer> map = Statistical(strings);
//map集合entryset
Set<Map.Entry<String, Integer>> entries = map.entrySet();
//入堆:实现小顶堆,输出到结果集就是堆的逆序,即大顶堆
for (Map.Entry<String, Integer> entry : entries) {
//将自己的节点放进堆中,以num小根形式
MyNode node = new MyNode(entry.getKey(), entry.getValue());
if (heap.size() < k) {
heap.add(node);
} else {
if (heap.peek().compareTo(node)< 0) {//堆顶元素大小 小于 剩余节点
//删除堆顶元素
heap.poll();
//添加剩余元素
heap.offer(new MyNode(entry.getKey(), entry.getValue()));
}
}
}
String[][] res = new String[k][2];
//从后往前输出最后K个堆节点
for (int i = k-1; i >=0; i--) {
MyNode node = heap.poll();
res[i][0] = node.val;
res[i][1] = String.valueOf(node.num);
}
return res;
}
//统计数组中字符出现次数
public static HashMap<String, Integer> Statistical(String[] strings) {
HashMap<String, Integer> countMap = new HashMap<>();
for (String string : strings) {
Integer value = countMap.get(string);
if (value == null) {
value = 0;
}
countMap.put(string, value + 1);
}
return countMap;
}
// public static void main(String[] args) {
// String[] s = {"i", "i", "i", "W", "W", "W", "2"};
// String[][] strings = topKstrings(s, 2);
// }
//自定义堆中节点结构,需要实现比较方法
static class MyNode implements Comparable<MyNode> {
String val;
int num;
MyNode(String val, int num) {
this.num = num;
this.val = val;
}
@Override
public int compareTo(MyNode o) {
if (this.num - o.num>0) {
return 1;
} else if(this.num - o.num<0){
return -1;
}else {
//按照字典顺序排
return o.val.compareTo(this.val);
}
}
}
}
查看7道真题和解析