一、题目

给一非空的单词列表,返回前 k 个出现次数最多的单词。
返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率,按字母顺序排序。

二、思路

1、哈希+优先队列

根据题意,首先需要记录每个单词出现的次数,然后根据出现的频率和字母顺序排序,取前k个即可。这么一说感觉有点复杂,拆解步骤一下:
1)记录每个单词出现次数
用一个哈希表,键为字符串,值为出现次数记录
2)优先队列进行排序
(使用链表进行排序也行,但为了减小时间复杂度使用优先队列)
建立优先队列,直接使用Map.Entry进行存储,队列排序规则为:

1、如果出现次数不等,出现次数小的在顶部 2、如果出现次数相等,使用String的compareTo进行对比

三、代码

1、哈希+优先队列

  1. class Solution {
  2. public List<String> topKFrequent(String[] words, int k) {
  3. Map<String, Integer> map = new HashMap<>();
  4. for (String word : words) {
  5. map.put(word, map.getOrDefault(word, 0) + 1);
  6. }
  7. Queue<Map.Entry<String, Integer>> q = new PriorityQueue<>(k, new Comparator<Map.Entry<String, Integer>>() {
  8. @Override
  9. public int compare(Map.Entry<String, Integer> e1, Map.Entry<String, Integer> e2) {
  10. if (e1.getValue() == e2.getValue()) {
  11. return e2.getKey().compareTo(e1.getKey());
  12. }
  13. return e1.getValue() - e2.getValue();
  14. }
  15. });
  16. for (Map.Entry<String, Integer> entry : map.entrySet()) {
  17. q.add(entry);
  18. if (q.size() > k) {
  19. q.poll();
  20. }
  21. }
  22. List<String> ans = new ArrayList();
  23. while (q.size() != 0) {
  24. ans.add(q.poll().getKey());
  25. }
  26. Collections.reverse(ans);
  27. return ans;
  28. }
  29. }

n为words中元素个数,时间复杂度为O(n+n*logk+k),空间复杂度为O(n+k)。