本文正在参加「Java主题月 – Java 刷题打卡」,详情查看 活动链接
题目描述
给一非空的单词列表,返回前 k 个出现次数最多的单词。
返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率,按字母顺序排序。
示例 1:
输入: ["i", "love", "leetcode", "i", "love", "coding"], k = 2
输出: ["i", "love"]
解析: "i" 和 "love" 为出现次数最多的两个单词,均为2次。
    注意,按字母顺序 "i" 在 "love" 之前。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/top-k-frequent-words
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
复制代码思路分析
- 阅读题目,得到关键信息首先是按照单词出现频率由高到低排序。如果不同的单词有相同出现频率,按字母顺序排序。
- 首先采用 HashMap 结构统计单词频率。TOP K 问题,一般采用 heap 结构来进行排序。Java 中比较常用的是 PriorityQueue。 为什么使用 PriorityQueue 呢? 这里简单的介绍一下:
An unbounded priority queue based on a priority heap. 
The elements of the priority queue are ordered according to their natural ordering, or by a Comparator provided at queue construction time, depending on which constructor is used.
A priority queue does not permit null elements.
复制代码上面这段介绍来自于官方文档, 简明扼要介绍了 PriorityQueue 的重点。
- 更多的 PriorityQueue 介绍信息,可以参考官方文档
- 在下面的代码中,我自定义了 WordNumber 数据结构,来记录单词和出现的频率,帮助理清思路。
- 在 PriorityQueue 的应用中,重写了 Comparator 满足题意要求!
代码
class WordNumber {
    String word;
    Integer number;
    public String getWord() {
        return word;
    }
    public void setWord(String word) {
        this.word = word;
    }
    public Integer getNumber() {
        return number;
    }
    public void setNumber(Integer number) {
        this.number = number;
    }
}
public class DayCode {
    public static void main(String[] args) {
        String[] words = new String[]{
                "i", "love", "leetcode", "i", "love", "coding"
        };
        int k = 2;
        String[] words1 = new String[]{
                "a", "aa", "aaa"
        };
        int k1 = 1;
        List<String> ans = new DayCode().topKFrequent(words, k);
        System.out.println(ans.toString());
        List<String> ans1 = new DayCode().topKFrequent(words1, k1);
        System.out.println(ans1.toString());
    }
    public List<String> topKFrequent(String[] words, int k) {
        Map<String, Integer> map = new HashMap<>();
        for (String word : words) {
            map.put(word, map.getOrDefault(word, 0) + 1);
        }
        PriorityQueue<WordNumber> priorityQueue = new PriorityQueue<>(
                new Comparator<WordNumber>() {
                    @Override
                    public int compare(WordNumber o1, WordNumber o2) {
                        if (o1.getNumber().equals(o2.getNumber())) {
                            return o1.getWord().compareTo(o2.getWord());
                        } else {
                            return o2.getNumber() - o1.getNumber();
                        }
                    }
                }
        );
        for (Map.Entry<String, Integer> i : map.entrySet()) {
            WordNumber WordNumber = new WordNumber();
            WordNumber.setWord(i.getKey());
            WordNumber.setNumber(i.getValue());
            priorityQueue.add(WordNumber);
        }
        List<String> ans = new ArrayList<>();
        for (int i = 0; i < k; i++) {
            WordNumber temp = priorityQueue.poll();
            ans.add(temp.getWord());
        }
        return ans;
    }
}
复制代码提交测试:

总结
- 这个题目很好,在实际业务开发中很常用。上述解法的时间复杂度是 O(n log n), 空间复杂度是 O(n)
- 纸上得来终觉浅,绝知此事要躬行。建议大家有时间也一起写一下这个题目,我们一起掌握这个题目!
- 坚持每日一题,加油!
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
    





















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)
