闲话跳过
2022/4/6华子的春招笔试题第一道就是这个类似的
楼主当场抓瞎了
于是笔试也寄了
下来赶紧女娲补天一下吧
leetcode692原题
输入参数 String[] words,int k
解释:words数组存储一堆词,k代表需要输出的前k个高频词
如果出现次数相同,则按照字典序排序
输出:List<String> res
解释:依次为k个高频词
题解
这是网上大佬的题解,侵删
class Solution {
public List<String> topKFrequent(String[] words, int k) {
Map<String, Integer> cnt = new HashMap<String, Integer>();
for (String word : words) {
cnt.put(word, cnt.getOrDefault(word, 0) + 1);
}
PriorityQueue<Map.Entry<String, Integer>> pq = new PriorityQueue<Map.Entry<String, Integer>>(new Comparator<Map.Entry<String, Integer>>() {
public int compare(Map.Entry<String, Integer> entry1, Map.Entry<String, Integer> entry2) {
return entry1.getValue() == entry2.getValue() ? entry2.getKey().compareTo(entry1.getKey()) : entry1.getValue() - entry2.getValue();
}
});
for (Map.Entry<String, Integer> entry : cnt.entrySet()) {
pq.offer(entry);
if (pq.size() > k) {
pq.poll();
}
}
List<String> ret = new ArrayList<String>();
while (!pq.isEmpty()) {
ret.add(pq.poll().getKey());
}
Collections.reverse(ret);
return ret;
}
}
简单说一下思路
- HashMap cnt存储words,key为words,value为出现次数
- PriorityQueue pq将HashMap中键值对排序
- 排序的规则为如果两个words的出现次数不一样,则出现次数多的在前面
- 如果两个words出现一样,则按字典序排序
- 整个优先队列维持size为k,如果大于k,将最小频率的那个word poll
- 将pq中的key值转移到List<String> ret中
- 因为优先队列是先进后出的,所以将ret逆序
- ret则为结果
HashMap方法getOrDefault()
Map.getOrDefault(Object key, V defaultValue)方法的作用是:
当Map集合中有这个key时,就使用这个key值;
如果没有就使用默认值defaultValue。
代码示例如下:
HashMap<String, String> map = new HashMap<>();
map.put("name", "cookie");
map.put("age", "18");
map.put("sex", "女");
String name = map.getOrDefault("name", "random");
System.out.println(name);// cookie,map中存在name,获得name对应的value
int score = map.getOrDefault("score", 80);
System.out.println(score);// 80,map中不存在score,使用默认值80
Map.Entry<K,V>
Map.Entry是Map声明的一个内部接口,此接口为泛型,定义为Entry<K,V>。它表示Map中的一个实体(一个key-value对)。接口中有getKey(),getValue方法。
- 使用Map.Entry<>遍历HashMap
for (Map.Entry<String, Integer> entry : cnt.entrySet()) {
pq.offer(entry);
if (pq.size() > k) {
pq.poll();
}
}
- getKey() getValue()方法
public static void main(String[] args) {
Map<Integer,String> maps=new HashMap<Integer,String>();
maps.put(3,"张飞");
maps.put(2,"关羽");
maps.put(4,"赵云");
maps.put(1,"刘备");
maps.put(5,"马超");
Set<Map.Entry<Integer,String>> sets=maps.entrySet();
for(Map.Entry<Integer,String> entry:sets){
System.out.println("key="+entry.getKey()+" value="+entry.getValue());
}
}
Comparator
Comparator接口定义了两个方法:compare( )和equals( )。这里给出的compare( )方法按顺序比较了两个元素:
int compare(Object obj1, Object obj2)
obj1和obj2是被比较的两个对象。当两个对象相等时,该方法返回0;当obj1大于obj2时,返回一个正值;否则,返回一个负值。如果用于比较的对象的类型不兼容的话,该方法引发一个ClassCastException异常。通过覆盖compare( ),可以改变对象排序的方式。例如,通过创建一个颠倒比较输出的比较函数,可以实现按逆向排序。
这里给出的equals( )方法,测试一个对象是否与调用比较函数相等:
boolean equals(Object obj)
obj是被用来进行相等测试的对象。如果obj和调用对象都是Comparator的对象并且使用相同的排序。该方法返回true.否则返回false.重载equals( )方法是没有必要的,大多数简单的比较函数都不这样做。
List<Student> stus = new ArrayList<Student>(){
{
add(new Student("张三", 30));
add(new Student("李四", 20));
add(new Student("王五", 60));
}
};
// 1.对学生集合按年龄进行排序
Collections.sort(stus, new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
// 升序
//return s1.getAge()-s2.getAge();
return s1.getAge().compareTo(s2.getAge());
// 降序
// return s2.getAge()-s1.getAge();
// return s2.getAge().compareTo(s1.getAge());
}
});
// 2.对学生集合按姓名首字母排序
Comparator comparator = Collator.getInstance(Locale.CHINA);
Collections.sort(stus, new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
return comparator.compare(s1.getName(), s2.getName());
}
});
// 输出结果
...
Collections.reverse()
reverse(List<?>) 方法被用来反转指定列表中的元素的顺序.
感觉挺好用的,但是查了一下好像只能逆序列表