📅  最后修改于: 2023-12-03 15:26:08.964000             🧑  作者: Mango
给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
使用堆(优先队列)来解决这个问题,堆可以把时间复杂度降到 O(nlogk)。
具体实现如下:
遍历数组,使用哈希表(字典)统计每个元素的出现次数,并记录最大出现次数 max_freq。
定义一个最小堆,把元素和它对应的出现次数放到堆里面,堆的大小为 k。
遍历哈希表,对于每个元素,如果出现次数大于最小堆堆顶的元素的出现次数,就把堆顶元素弹出,把当前元素和它的出现次数加入堆中。
最后,输出堆中的 k 个元素即可。
代码实现如下所示:
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
# 哈希表统计每个元素的出现次数
freq_dict = {}
max_freq = 0
for num in nums:
freq_dict[num] = freq_dict.get(num, 0) + 1
max_freq = max(max_freq, freq_dict[num])
# 定义一个最小堆,堆中元素是 (出现次数, 元素) 的元组
heap = []
for num, freq in freq_dict.items():
# 把元素和对应的出现次数放入堆中
heapq.heappush(heap, (freq, num))
# 如果堆的大小超过了 k,就弹出堆顶元素(出现次数最小的元素)
if len(heap) > k:
heapq.heappop(heap)
# 输出堆中的 k 个元素,注意堆中元素的顺序是相反的,因此要反转一下
return [x[1] for x in reversed(heap)]
遍历数组需要 O(n) 的时间,遍历哈希表需要 O(n) 的时间,向堆中插入元素和弹出堆顶元素需要 O(logk) 的时间,因此总时间复杂度是 O(nlogk)。
哈希表的大小为 O(n),堆的大小为 O(k),因此空间复杂度是 O(n+k)。
这道题目考察了对堆(优先队列)的理解和使用。堆可以帮助我们快速在一组元素中找到最大或最小的元素,它的时间复杂度为 O(logn)。在解决这个问题时,我们通过把元素和它的出现次数放到堆中,并限制堆的大小为 k,来找到出现频率前 k 高的元素,时间复杂度为 O(nlogk)。