📅  最后修改于: 2023-12-03 15:23:33.874000             🧑  作者: Mango
在大多数数据处理的应用中,需要能查找出序列(如数组)中出现最频繁的K个元素。这个问题也被称为“topK问题”。
本文介绍两种解决方案:哈希表和堆排序。
哈希表是一种数据结构,可以将一些键和对应的值相互映射起来。通过哈希函数,可以将一个键转换为它所对应的哈希值。哈希表可以在O(1)的时间复杂度下完成插入、删除和查找操作。
对于数组中查找第K个最常出现的元素,可以先用一个哈希表记录每个元素出现的次数,然后将哈希表中的键值对按照值进行排序,最后取出前K个元素即可。
def topk(arr, k):
num_dict = {}
for num in arr:
num_dict[num] = num_dict.get(num, 0) + 1
sorted_nums = sorted(num_dict.items(), key=lambda x: x[1], reverse=True)
res = [x[0] for x in sorted_nums[:k]]
return res
上述代码中,首先定义了一个字典num_dict,用于记录每个元素出现的次数。然后通过遍历数组arr,将元素出现的次数存储到num_dict中。最后,将num_dict按照value进行排序,取出前K个元素的key返回即可。
堆排序是一种利用堆的数据结构的排序算法。具体来说,可以通过维护一个大小为K的小根堆(或大根堆),将数组中所有元素加入堆中。最后,堆中的前K个元素就是数组中出现次数最大的K个元素。
import heapq
def topk(arr, k):
num_dict = {}
for num in arr:
num_dict[num] = num_dict.get(num, 0) + 1
heap = []
for num, count in num_dict.items():
if len(heap) < k:
heapq.heappush(heap, (count, num))
else:
if count > heap[0][0]:
heapq.heappushpop(heap, (count, num))
res = [x[1] for x in heap]
return res
上述代码中,首先定义了一个字典num_dict,用于记录每个元素出现的次数。然后,定义了一个空堆heap。遍历num_dict的每一个键值对,对于堆未满的情况下,将元素和出现次数加入堆中。对于堆已满的情况下,将元素和出现次数和堆顶元素的次数比较。如果大于堆顶元素的次数,则将堆顶元素弹出并加入当前元素。最后,将堆中的元素返回即可。