一,先看一下题目
给一非空的单词列表,返回前 k 个出现次数最多的单词。
返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率,按字母顺序排序。
看完题目你是不是已经有了想法??????
TopK???
NO!!!
(慢慢品)
二,解题思路
1.借助Map统计各个单词的出现次数
2.把键值对组织到一个ArrayList中
3.按照题目要求进行降序排序(出现次数+字典序)
不多说!!!!下面才是重点
三,上代码(看点在这里)
先把统计结果放入一个ArrayList
public List<String> topKFrequent(String[] words,int k){
//先统计各单词出现次数
Map<String,Integer> map = new HashMap<>();
for (String s : words ) {
int count = map.getOrDefault(s,0);//获取到当前单词出现次数
map.put(s,count+1);//存入map中
}
//把刚才统计到的字符串放到ArrayList中
//KeySet相当于得到了一个Set,Set中存放的就是所有的key
ArrayList<String> arrayList = new ArrayList(map.keySet());
//按照刚才的统计次数,针对ArrayList进行排序
接下来就开始表演了
1.使用集合类Collections自带的sort方法对ArrayList进行排序
注意: sort默认按元素自身大小进行升序排序(String的字典序) 此处我们要按照字符串出现次数降序排序,也就需要比较器自定制比较规则
思考:这里我们用Comparable行不行???
答案:不行 原因:因为我们是针对String进行制定比较规则,要比较就要更改String源码,你能改吗?
所以我们得重新写一个比较器,来指定String什么算大,什么算小
static class MyComparator implements Comparator<String>{
private Map<String,Integer> map;
public MyComparator(Map<String, Integer> map) {
this.map = map;
}
@Override
public int compare(String o1, String o2) {
int count1 =map.get(o1);
int count2 = map.get(o2);
if(count1 == count2){
//String自身实现了Comparable,自带字典序的比较功能
//CompareTo就是使用String默认的比较规则
return o1.compareTo(o2);
}
return count2-count1;
}
}
public List<String> topKFrequent(String[] words,int k){
//先统计各单词出现次数
Map<String,Integer> map = new HashMap<>();
for (String s : words ) {
int count = map.getOrDefault(s,0);//获取到当前单词出现次数
map.put(s,count+1);//存入map中
}
//把刚才统计到的字符串放到ArrayList中
//KeySet相当于得到了一个Set,Set中存放的就是所有的key
ArrayList<String> arrayList = new ArrayList(map.keySet());
Collections.sort(arrayList,new MyComparator(map));
return arrayList.subList(0,k);
}
2.使用匿名内部类(语法糖)
什么时候用到内部匿名类??
这个类只用一次,用完就丢了
public List<String> topKFrequent(String[] words,int k){
//先统计各单词出现次数
Map<String,Integer> map = new HashMap<>();
for (String s : words ) {
int count = map.getOrDefault(s,0);//获取到当前单词出现次数
map.put(s,count+1);//存入map中
}
//把刚才统计到的字符串放到ArrayList中
//KeySet相当于得到了一个Set,Set中存放的就是所有的key
ArrayList<String> arrayList = new ArrayList(map.keySet());
Collections.sort(arrayList, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int count1 = map.get(o1);
int count2 = map.get(o2);
if(count1 == count2){
return o1.compareTo(o2);
}
return count2-count1;
}
});
return arrayList.subList(0,k);
}
3.使用lambda表达式(语法糖)
lambda表达式,本质上就是一个匿名方法
public List<String> topKFrequent(String[] words,int k){
//先统计各单词出现次数
Map<String,Integer> map = new HashMap<>();
for (String s : words ) {
int count = map.getOrDefault(s,0);//获取到当前单词出现次数
map.put(s,count+1);//存入map中
}
//把刚才统计到的字符串放到ArrayList中
//KeySet相当于得到了一个Set,Set中存放的就是所有的key
ArrayList<String> arrayList = new ArrayList(map.keySet());
Collections.sort(arrayList, (o1, o2) ->{
int count1 = map.get(o1);
int count2 = map.get(o2);
if(count1 == count2){
return o1.compareTo(o2);
}
return count2-count1;
});
return arrayList.subList(0,k);
}