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)
节约内存,降低时间复杂度。
1172

被折叠的 条评论
为什么被折叠?



