每日一题 692. 前K个高频单词

692. 前K个高频单词

难度:中等
语言:java

题目内容

给一非空的单词列表,返回前 k 个出现次数最多的单词。

返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率,按字母顺序排序。
在这里插入图片描述

解法分析

这个很容易能够想到哈希表的方法来记录出现次数,主要还有个按照字母顺序排序的要求。有两种解法可以解决,一个是排序解法,还有一种是小根堆,小根堆在最近的题目中出现蛮多次的,是一种比较简单的排序方法。
先看排序的解法,使用ArrayList的lambda排序方法来进行排序,这是一个比较简单的方法打,JDK8带来的lambda表达式,让List的排序简单了非常多:

class Solution {
    public List<String> topKFrequent(String[] words, int k) {
        Map<String,Integer> ansmap = new HashMap<>();
        for (String s:words){
            ansmap.put (s,ansmap.getOrDefault(s,0)+1);
        }
        List<String> ans = new ArrayList<>(ansmap.keySet());
        ans.sort((a, b) -> {
            if (ansmap.get(a).equals(ansmap.get(b))) {
                return a.compareTo(b);
            } else {
                return ansmap.get(b) - ansmap.get(a);
            }
        });
        return ans.subList(0, k); 
    }
}

接下来再来看小根堆的方法,这个方法我之前没学会写,就借鉴一下答案来看。

public class Solution {

     public List<String> topKFrequent(String[] words, int k) {
        // 1.先用哈希表统计单词出现的频率
        Map<String, Integer> count = new HashMap();
        for (String word : words) {
            count.put(word, count.getOrDefault(word, 0) + 1);
        }
        // 2.构建小根堆,相比List,这里可以直接写出排序规则,跟List也类似
        PriorityQueue<String> minHeap = new PriorityQueue<>((s1, s2) -> {
            if (count.get(s1).equals(count.get(s2))) {
                return s2.compareTo(s1);
            } else {
                return count.get(s1) - count.get(s2);
            }
        });
        // 3.依次向堆加入元素。
        for (String s : count.keySet()) {
            minHeap.offer(s);
            // 当堆中元素个数大于 k 个的时候,需要弹出堆顶最小的元素。
            if (minHeap.size() > k) {
                minHeap.poll();
            }
        }
        // 4.依次弹出堆中的 K 个元素,放入结果集合中。
        List<String> res = new ArrayList<String>(k);
        while (minHeap.size() > 0) {
            res.add(minHeap.poll());
        }
        // 5.注意最后需要反转元素的顺序。
        Collections.reverse(res);
        return res;
    }        
}

其实看完了这个方法,并没有觉得简单很多,但是空间是节省了的,因为堆相比List所使用的空间只有O(K)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值