1. 程式人生 > >LeetCode:前K個高頻單詞【692】

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;
    }
}