692. 前K个高频单词
原始题目链接:https://leetcode-cn.com/problems/top-k-frequent-words/
给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。
返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序 排序。
示例 1:
输入: words = [“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 次。
解题思路:
前k个高频单词,可以想到使用堆这数据结构,因为Python只有小根堆,即父节点都小于等于它的左右孩子节点,构建堆可以使用heapq这个Python数据结构,构建的元素也可以是元组,这就方便记录词频和对应的单词,并且heapq自身可以维护堆内的顺序,由于求的是k个高频就是k个大的,小根堆可以使用词频的负数来反向构建堆,然后再弹出k个元素就是答案。当词频相同的时候,需要根据字典排序,在使用heapq这个数据结构的时候,构建的元素是元组,元祖的第一个元素是词频的负数,第二个元素是单词,小根堆内部维护顺序的时候会根据元组的第一个元素来比较,相同的话,根据元组第二个元素来比较,这就维护了一个字典序列的排序。
代码实现:
class Solution:
def topKFrequent(self, words: List[str], k: int) -> List[str]:
word_freq = {}
ans = []
# 统计每个单词的词频存入字典中
for word in words:
word_freq[word] = word_freq.setdefault(word, 0) + 1
# 构建一个小根堆,大小为k
# 入堆的元素是元祖(词频的负数, 单词)
# 因为求的k个出现最多,且Python只有小根堆这个数据结构,所以词频取负数
# 根据词频的负数维护大小为k的堆,这样每次弹出堆的元素是词频较小的单词
heap = []
# 遍历 词频-单词 字典,构建小根堆
for key, value in word_freq.items():
heapq.heappush(heap, (-value, key))
# 弹出k个元素
for _ in range(k):
ans.append(heapq.heappop(heap)[1])
return ans
参考文献:
https://leetcode-cn.com/problems/top-k-frequent-words/solution/692-qian-kge-gao-pin-dan-ci-zi-dian-dui-7v0bl/