LeetCode:前K个高频单词【692】

LeetCode:前K个高频单词【692】

题目描述

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

返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率,按字母顺序排序。

示例 1:

输入: ["i", "love", "leetcode", "i", "love", "coding"], k = 2
输出: ["i", "love"]
解析: "i" 和 "love" 为出现次数最多的两个单词,均为2次。
    注意,按字母顺序 "i" 在 "love" 之前。

示例 2:

输入: ["the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"], k = 4
输出: ["the", "is", "sunny", "day"]
解析: "the", "is", "sunny" 和 "day" 是出现次数最多的四个单词,
    出现次数依次为 4, 3, 2 和 1 次。

注意:

  1. 假定 k 总为有效值, 1 ≤ k ≤ 集合元素数。
  2. 输入的单词均由小写字母组成。

题目分析

  这道题是前K个高频元素【347】的进阶。难度主要增加在对结果的处理:

  • 首先,结果按照单词的出现次数递减排列。
  • 相同频率的单词按照子母序列排序。

  我们先处理第一个问题,出现次数递减,我们知道,优先队列的是小顶堆,转换为列表后呈递增形式,我们使用集合方法将它逆转即可

  然后是第二个问题,我们在最后会对取出来的集合进行逆转操作,所以我们在设计比较器的时候,要让字母序大的在前面,比如a,b的出现次数相同,我们在比较器中先让b处在a的前面,最后逆转操作时,a就到了b的前面

Java题解

class Solution {
    public List<String> topKFrequent(String[] words, int k) {
             Map<String,Integer> countMap = new HashMap<>();
        for(String word:words)
            countMap.put(word,countMap.getOrDefault(word,0)+1);

        PriorityQueue<String> priorityQueue = new PriorityQueue<>(k, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return countMap.get(o1).equals(countMap.get(o2))?o2.compareTo(o1):countMap.get(o1)-countMap.get(o2);
            }
        });
        for (String word : countMap.keySet()) {
            priorityQueue.offer(word);
            if (priorityQueue.size() > k) {
                priorityQueue.poll();
            }
        }
        List<String> ans = new ArrayList<>();
        while (!priorityQueue.isEmpty()) ans.add(priorityQueue.poll());
        Collections.reverse(ans);
        return ans;
    }
}
原文地址:https://www.cnblogs.com/MrSaver/p/9990811.html