top-k的应用

top-k的应用

topk指的是,保存一段数据的最大或者最小的k位数,在code中或者工程中右很重要的应用。
举例:
查询超大量数据中 最小或者最大的 第 k位数。
正常使用排序
缺点:内存占用会超出正常范围
相对简单的做法是,遍历K次,每次选出最小(或者最大的)数。最后返回结果
缺点:时间复杂度为KN,而且需要删除原数据中的数或者要在已有数据中进行判断
简化:
形成一个topk的 最大堆。内部使用堆排序的 shiftup 以及 shiftdown。从左到右进行遍历一次。最后pop root即可找到答案。时间复杂度(Nlogk)

215. Kth Largest Element in an Array

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.

Example 1:

Input: [3,2,1,5,6,4] and k = 2
Output: 5
Example 2:

Input: [3,2,3,1,2,4,5,5,6] and k = 4
Output: 4

代码:

class kheap:
    def __init__(self):
        self.heap = []
        
    def shift_up(self,x):
        self.heap.append(x)
        l = len(self.heap)
        i = l-1
        while i>0:
            root = (i-1)//2
            if self.heap[root]>self.heap[i]:
                self.heap[i],self.heap[root] = self.heap[root],self.heap[i]
            else:
                break
            i = root
    
    def shift_down(self):
        if len(self.heap)==0:
            return 
        elif len(self.heap) == 1:
            return self.heap.pop()
        
        tar = self.heap.pop(0)
        self.heap = [self.heap[-1]] + self.heap[:-1]
        l = len(self.heap)
        i = 0
        while i <= (l-2)//2:
            left = 2*i+1
            right = 2*i+2
            if right <= l-1:
                if self.heap[i]>self.heap[left] and self.heap[left]<=self.heap[right]:
                    self.heap[i],self.heap[left] = self.heap[left],self.heap[i]
                    i=left
                elif self.heap[i]>self.heap[right] and self.heap[right]<=self.heap[left]:
                    self.heap[i],self.heap[right] = self.heap[right],self.heap[i]
                    i=right
                else:
                    break
            else:
                if self.heap[i]>self.heap[left]:
                    self.heap[i],self.heap[left] = self.heap[left],self.heap[i]
                    i=left
                else:
                    break
        return tar

字节跳动面试题:在一个无序数组中,每个元素与排序好的位置距离<=k,对数组进行排序

最小堆然后遍历
代码:

class Solution:
    def k_sort(self,arr,k):
        myheap = kheap()
        for i in range(k):
            if not arr:
                break
            myheap.shift_up(arr.pop(0))
        res = []
        while  arr:
            myheap.shift_up(arr.pop(0))
            res.append(myheap.shift_down())
            #print(res,'#')
        while myheap.heap:
            res.append(myheap.shift_down())
        return res

class kheap:
    def __init__(self):
        self.heap = []

    def shift_up(self, x):
        self.heap.append(x)
        l = len(self.heap)
        i = l - 1
        while i > 0:
            root = (i - 1) // 2
            if self.heap[root] > self.heap[i]:
                self.heap[i], self.heap[root] = self.heap[root], self.heap[i]
            else:
                break
            i = root

    def shift_down(self):
        if len(self.heap) == 0:
            return
        elif len(self.heap) == 1:
            return self.heap.pop()

        tar = self.heap.pop(0)
        self.heap = [self.heap[-1]] + self.heap[:-1]
        l = len(self.heap)
        i = 0
        while i <= (l - 2) // 2:
            left = 2 * i + 1
            right = 2 * i + 2
            if right <= l - 1:
                if self.heap[i] > self.heap[left] and self.heap[left] <= self.heap[right]:
                    self.heap[i], self.heap[left] = self.heap[left], self.heap[i]
                    i = left
                elif self.heap[i] > self.heap[right] and self.heap[right] <= self.heap[left]:
                    self.heap[i], self.heap[right] = self.heap[right], self.heap[i]
                    i = right
                else:
                    break
            else:
                if self.heap[i] > self.heap[left]:
                    self.heap[i], self.heap[left] = self.heap[left], self.heap[i]
                    i = left
                else:
                    break
        return tar

su = Solution()
arr = [2,3,1,6,4,8,7,5,11,9,10]
k = 3
res = su.k_sort(arr,k)
print(res)

节约内存,降低时间复杂度。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值