leetcode692学习优先队列和Comparator

闲话跳过

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<?>) 方法被用来反转指定列表中的元素的顺序.
感觉挺好用的,但是查了一下好像只能逆序列表

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值