topK问题

2019-03-26  本文已影响0人  Haward_

(1)时间复杂度分析:
每次调用'self.heapAdjust(self.arr, n, i)'的时间复杂度是O(lgn)(只需要走完树的深度h的时间次数),需要调用O(n)次,总的时间是O(nlgn)
(2)树的深度求解(边的数目==结点数目-1,结点都唯一的跟它上面的一条边链接):
二叉树的从上往下,1棵变2棵,2棵子树变成4棵树,4又变8.。。,即:2^1+...+2^h=(n-1)/2(有多少项,树的高度就是多少),由等比数列有:2^h=nh=log_2n(即树的高度跟log_2n是线性关系)

"""
topk问题思想:假设是返回数组中最大的k个数。
(1)借助于堆排序的思想,用一个长度为k的数字arr去维护
最大的k个数,len(arr)<k的时候,直接插入.
(2)当len(arr)==k的时候,这个时候需要建立堆,
然后堆顶的元素在插入时候需要跟新元素e比较的(采用堆顶比较只需要从root
往下调整一次就好),如果e大于堆顶元素,那么堆顶元素被替换为e,然后需要
从root往下调整一次。
"""
class Solution:
    def __init__(self,capacity):
        self.arr = []
        self.capacity = capacity

    def insert(self,e):
        if len(self.arr)<self.capacity:
            self.arr.append(e)
            return
        #建立堆的过程
        n = len(self.arr)
        #int(n/2-1)保证了非叶子结点,n是最大的index+1
        for i in range(int(n/2-1),-1,-1):
            self.heapAdjust(self.arr, n, i)
        #调整堆的过程
        if e>self.arr[0]:
            self.arr[0] = e
            self.heapAdjust(self.arr,n,0)

    def heapAdjust(self,arr,n,i):
        minest = i
        left = i*2+1
        right = i*2+2
        if left<n and arr[left]<arr[minest]:
            minest = left
        if right<n and arr[right]<arr[minest]:
            minest = right
        if i!=minest:
            arr[i],arr[minest] = arr[minest],arr[i]
            self.heapAdjust(arr,n,minest)


if __name__ == "__main__":
    k = 3
    nums=[1,3,6,5,9,8,11,20]
    so = Solution(k)
    for e in nums:
        so.insert(e)
        print(so.arr)

上一篇 下一篇

猜你喜欢

热点阅读