692. 前K个高频单词[中等]

75 阅读1分钟

题目

给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。

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

  • 来源:力扣(LeetCode)
  • 链接:leetcode.cn/problems/to…
  • 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法一

思路

  • Map统计
  • 最小堆获取topk

代码一

    public static List<String> topKFrequent(String[] words, int k) {
        Map<String, Integer> map = new HashMap<>();
        for (String word : words) {
            Integer count = map.get(word);
            if (count == null) {
                map.put(word, 1);
            } else {
                map.put(word, ++count);
            }
        }
        Queue<Word> queue = new PriorityQueue<>();
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            Word word = new Word(entry.getKey(), entry.getValue());
            queue.offer(word);
            if (queue.size() > k) {
                queue.poll();
            }
        }

        List<String> list = new LinkedList<>();
        while (!queue.isEmpty()) {
            list.add(queue.poll().word);
        }
        Collections.reverse(list);
        return list;
    }

    private static class Word implements Comparable<Word> {
        private String word;
        private int count;

        public Word(String word, int count) {
            this.word = word;
            this.count = count;
        }

        public int compareTo(Word that) {
            return this.count == that.count ? that.word.compareTo(this.word) : this.count - that.count;
        }
    }

复杂度

  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(n)
  • 上面的代码击败79%

代码二

最后输出的时候,需要反转。可以使用Deque。


public static List<String> topKFrequent(String[] words, int k) {
    Map<String, Integer> map = new HashMap<>();
    for (String word : words) {
        Integer count = map.get(word);
        if (count == null) {
            map.put(word, 1);
        } else {
            map.put(word, ++count);
        }
    }
    Queue<Word> queue = new PriorityQueue<>();
    for (Map.Entry<String, Integer> entry : map.entrySet()) {
        Word word = new Word(entry.getKey(), entry.getValue());
        queue.offer(word);
        if (queue.size() > k) {
            queue.poll();
        }
    }

    Deque<String> deque = new LinkedList<>();
    while (!queue.isEmpty()) {
        deque.offerFirst(queue.poll().word);
    }
    return new LinkedList<>(deque);
}

private static class Word implements Comparable<Word> {
    private String word;
    private int count;

    public Word(String word, int count) {
        this.word = word;
        this.count = count;
    }

    public int compareTo(Word that) {
        return this.count == that.count ? that.word.compareTo(this.word) : this.count - that.count;
    }
}

上面的代码击败了99.5%。