前 K 个高频元素-队列

前 K 个高频元素

思路

  • 优先级队列:以优先级为堆的排序依据,用小顶堆
  1. 统计元素出现的次数:用dict,建立元素与次数之间的映射,O(n)
  2. 对次数进行排序: 前k个数构造规模为 k+1 的最小堆 minheap,+1 是因为占位节点; 遍历规模k之外的数据,大于堆顶则入堆,下沉维护规模为k的最小堆 minheap,O(nlogk)。
  3. 找出前k个高频元素:小顶堆最先弹出是最小值,倒序输出到数组。
  • 相关知识:
  • 优先队列,本质是堆,而堆是完全二叉树,树中每个结点的值都不小于(或不大于)其左右孩子的值.
    大顶堆:父节点大于等于左右孩子的值,堆头是最大的
    小顶堆:父节点小于等于左右孩子的值,堆头是最小的
  • topk 问题:最大堆求topk小,最小堆求 topk 大。
    1)求topk大:构建一个 k 个数的最小堆,当读取的数大于根节点时,替换根节点,重新塑造最小堆。
    2)求topk小:构建一个 k 个数的最大堆,当读取的数小于根节点时,替换根节点,重新塑造最大堆。
class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        my_map=dict()
        #计算每个数出现频次
        for i in range(len(nums)):
            my_map[nums[i]]=my_map.get(nums[i],0)+1
        
        #小顶堆,对频次进行排序
        my_heap=[]
        for key,freq in my_map.items():
            #把freq,key作为二元组放入小顶堆
            heapq.heappush(my_heap,(freq,key))
            if len(my_heap)>k:
                #若堆大于K,弹出堆顶元素,保证堆大小一直为k
                heapq.heappop(my_heap)
        
        #找出前K个高频元素,小顶堆先弹出最小,所以倒序输出到数组
        res=[0]*k
        for i in range(k-1,-1,-1):
            #放入堆的是二元组(freq,key),key对应索引1
            res[i]=heapq.heappop(my_heap)[1]
        return res

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值