zoukankan      html  css  js  c++  java
  • 取topK

    从小到大取topK个数

    方法一:快排的思想,当划分节点的前面刚好为k-1个,把到pivot的值返回就可以了。

     1 class Solution:
     2     def __init__(self,arr):
     3         self.arr = arr
     4     def topK(self,k):
     5         n = len(self.arr)
     6         if k <=0 or k >=n:
     7             return []
     8         low = 0
     9         high = n-1
    10         mid = self.partition(low,high)
    11         while k-1 != mid:
    12             if k-1 > mid:
    13                 low = mid+1
    14                 mid = self.partition(low,high)
    15             elif k-1 < mid:
    16                 high = mid - 1
    17                 mid = self.partition(low,high)
    18         res = self.arr[:mid+1]
    19         print(res)
    20 
    21     def partition(self,low,high):
    22         pivotKey = self.arr[low]
    23         while low < high:
    24             while low < high and self.arr[high]>=pivotKey:
    25                 high-=1
    26             self.arr[low],self.arr[high]=self.arr[high],self.arr[low]
    27             while low < high and self.arr[low]<=pivotKey:
    28                 low+=1
    29             self.arr[low], self.arr[high] = self.arr[high], self.arr[low]
    30         return low
    31 
    32 if __name__ == "__main__":
    33     Solution([4,3,6,7,2,8,0,1]).topK(6)

    方法二:堆排序

    一个很常见的例子,假设我们要选5个最矮的同学参加比赛,候选人选好之后又跑来一个新同学参加评选。这个时候新同学只需要PK候选人中最高的,如果他比最高的还高,就被淘汰,如果比最高的矮,他就可以替代这个最高的。按照这个思想,无论再来多少新同学都可以很快速的选择。

    以这个思想为基础,为了最快的找到候选人中最高的,以身高为基准建立大顶堆,每次新人与堆顶PK,PK结束之后维护候选人重新为大顶堆。

    这种思想将时间复杂度降到以k为基数,每次调整堆的时间复杂度都是,那么整体时间复杂度为。

     1 class Solution2:
     2     def topK(self,nums,k):
     3         n = len(nums)
     4         if k <= 0 or k > n:
     5             return []
     6         # 建立大顶堆
     7         for i in range((k//2)-1, -1, -1):
     8             self.heapAjust(nums,i,k-1)
     9         for i in range(k,n):
    10             if nums[i]<nums[0]:
    11                 nums[0],nums[i]=nums[i],nums[0]
    12                 # 调整前k个数
    13                 self.heapAjust(nums,0,k-1)
    14         print(nums[:k])
    15     def heapAjust(self,nums,start,end):
    16         temp = nums[start]
    17         # 记录较大的那个孩子下标
    18         child = 2 * start + 1
    19         while child <= end:
    20             # 比较左右孩子,记录较大的那个
    21             if child + 1 <= end and nums[child] < nums[child+1]:
    22                 # 如果右孩子比较大,下标往右移
    23                 child += 1
    24             # 如果根已经比左右孩子都大了,直接退出
    25             if temp >= nums[child]:
    26                 break
    27             # 如果根小于某个孩子,将较大值提到根位置
    28             nums[start] = nums[child]
    29             # 接着比较被降下去是否符合要求,此时的根下标为原来被换上去的那个孩子下标
    30             start = child
    31             child = child * 2 + 1
    32         # 最后将一开始的根值放入合适的位置
    33         nums[start] = temp

    原文链接:https://blog.csdn.net/qq_20141867/article/details/81152894

  • 相关阅读:
    安装minio单机
    linux使用某非root用户执行开机启动项
    Maven Plugin fork 在 pom.xml中的作用
    Sourcetree 使用之 git add, git commit, git push, git reset commit
    idea远程debug k8s容器服务
    WebService Client端
    Maven编译外部jar包问题
    Sourcetree 使用之 git stash save 和 git stash pop
    Sybase 相关
    FW300R手机不能上网解决方法
  • 原文地址:https://www.cnblogs.com/NPC-assange/p/12153616.html
Copyright © 2011-2022 走看看