手撕推排序

  1. 前 K 个高频元素
    在这里插入图片描述
class Solution:

    # 小根堆调整
    def heapAdjust(self,L,start,end):
        i = start; j = 2*i; temp = L[start]
        while j <= end:
            if j < end and L[j][1] > L[j+1][1]:
                j = j+1
            if temp[1] > L[j][1]:
                L[i] = L[j]; i = j; j = 2*i
            else:
                break
        L[i] = temp

    # 建立小根堆
    def heapify(self,L, start, end):
        firstSortCount = end // 2
        for i in range(firstSortCount):
            self.heapAdjust(L,firstSortCount - i, end)
        return L

    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        dict1 = {}
        for i in nums: # 哈希表,复杂度O(n)
            if i not in dict1.keys():
                dict1[i]= 1
            else:
                dict1[i] = dict1[i] + 1
    
        List2 = [-1] # 第一个元素占位
        for item in dict1.keys():
            List2.append((item,dict1[item])) # 往列表里添加元组(key,nums)
       
        self.heapify(List2,1,k) # 列表[1:k]的元素建堆, 自底向上建堆 复杂度O(n)

        for item in List2[k+1:len(List2)]: # 获取top k ,遍历剩下的元素 ,复杂度O(nlogk)
            if item[1] > List2[1][1]: # 如果比堆顶元素大,就替换堆顶元素
                List2[1] = item
                self.heapAdjust(List2,1,k) # 替换后,调整为小根堆
            
        res = [i[0] for i in List2[1:k+1] ]
        res.sort() #对结果排序 复杂度O(klogk)
        return res
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值