【Leetcode 347】,前k个高频元素,小根堆的调整

本文介绍了如何使用Python实现一个算法,通过构建小根堆来找出给定数组中前k个出现频率最高的元素。主要涉及堆的下沉和上浮操作,以及collections.Counter用于统计元素频率。
摘要由CSDN通过智能技术生成

参考题解

题目:给定一个数组,输出 前k个高频元素。
思路:
遍历数组,建立小根堆(小根堆的元素是元组(num,freq),排序规则是每个元素的频率)。
下面使用数组‘heap’,函数’shift_down’,函数‘shift_up’等实现小根堆及其调整(上浮、下沉)。

 def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        def shift_down(arr,root,k):# 下沉的原因是,新换了堆顶,我们需要为这个堆顶元素找到它在堆中的正确位置
        # k表示目前堆的有效大小
            val=arr[root] # root node : <num,freq>
            while root<<1 <k:
                child=root<<1
                if child|1<k and arr[child|1][1]<arr[child][1]:
                    child|=1
                if arr[child][1]<val[1]:
                    arr[root]=arr[child]
                    root=child
                else:
                    break
            arr[root]=val
        def shift_up(arr,child):
        # 上浮调整操作,
        # 上浮原因是,我们在堆的末尾添加了新元素,我们需要为这个新元素找到它在堆中的正确位置
            val=arr[child]
            while child>>1 >0 and arr[child>>1][1]>val[1]:
                arr[child]=arr[child>>1]
                child>>=1
            arr[child]=val

        stat=collections.Counter(nums)# 清点数组nums中的元素个数
        stat=list(stat.items())
        heap=[(0,0)] # 用(0,0)做垫底,为了实现在数组中方便找到父子节点之间的联系,如果父节点的索引是root,那么左孩子的索引是root<<1,右孩子的索引是(root<<1)|1。相反地,如果孩子的索引是child,那么父的索引是child>>1

        for i in range(k):
            heap.append(stat[i])
            shift_up(heap,len(heap)-1)
        for i in range(k,len(stat)):
            if heap[1][1]<stat[i][1]:
                heap[1]=stat[i]
                shift_down(heap,1,k+1)
        return [item[0] for item in heap[1:]]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值