Top K Frequent Words

題目:

https://leetcode.com/problems/top-k-frequent-words/

題意:

給定一個字串陣列,求其中k個頻率最高的字串。

解法:

[排序]
使用一個Map<String, Integer> map 來紀錄各個字串出現的次數,接著再靠出現的次數把key entry排列,最後輸出K個字串,此法最簡單,但是需要 $$O(NlogN)$$時間與 $$O(N)$$的空間複雜度。
class Solution {
    public List<String> topKFrequent(String[] words, int k) {
        Map<String, Integer> count = new HashMap();
        for (String word: words) {
            count.put(word, count.getOrDefault(word, 0) + 1);
        }
        List<String> candidates = new ArrayList(count.keySet());
        Collections.sort(candidates, (w1, w2) -> count.get(w1).equals(count.get(w2)) ?
                w1.compareTo(w2) : count.get(w2) - count.get(w1));

        return candidates.subList(0, k);
    }
}

[Heap]

多使用一個Heap來輔助來降低整個排序的時間複雜度,此heap以以下兩個條件來排序並不斷的維持k個元素,最後把所有元素輸出到陣列後反轉(因為此為min heap,需要不斷淘汰出現次數最少的字串)。

  • 字串的出現次數
  • 若出現的次數相同,則較短或較前字母的字為先。

此法只需要 $$O(NlogK + K)$$時間與$$O(N + K)$$的空間。

class Solution {
    public List<String> topKFrequent(String[] words, int k) {
        List<String> result = new ArrayList<>();
        if (words == null || words.length == 0 || k == 0) {
            return result;
        }

        Map<String, Integer> map = new HashMap<>();
        for (String word : words) {
            map.put(word, map.getOrDefault(word, 0) + 1);
        }

        PriorityQueue<String> queue = new PriorityQueue<>(
            (w1, w2) -> {
                if (map.get(w1) == map.get(w2)) {
                    return w2.compareTo(w1);
                } else {
                    return map.get(w1) - map.get(w2);
                }
            }
        );

        for (String key : map.keySet()) {
            queue.offer(key);
            if (queue.size() > k) {
                queue.poll();
            }
        }

        while (!queue.isEmpty()) {
            result.add(queue.poll());
        }

        Collections.reverse(result);
        return result;

    }
}

results matching ""

    No results matching ""