精华内容
下载资源
问答
  • pythontopk算法实例

    2020-09-17 14:58:46
    主要介绍了pythontopk算法实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • python TopK算法

    2019-09-20 10:42:43
    TopK算法 寻找数组中的最小的k个数,也叫topk问题。 该算法要解决的问题是:在线性时间内找到一个无序序列中第kk大的数。 如:输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个...

    TopK算法

    寻找数组中的最小的k个数,也叫topk问题。

    该算法要解决的问题是:在线性时间内找到一个无序序列中第 kk 大的数。

    如:输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。

    思路:

    快速排序的 partition() 方法,会返回一个整数 j 使得 a[l…j-1] 小于等于 a[j],且 a[j+1…h] 大于等于 a[j],此时 a[j] 就是数组的第 j 大元素。可以利用这个特性找出数组的第 K 个元素,这种找第 K 个元素的算法称为快速选择算法。

     

    # -*- coding: gbk -*-
    def partition(seq):
        pi, seq = seq[0], seq[1:]                 # 选取并移除主元
        lo = [x for x in seq if x <= pi]#选出小于第一个数的所有元素
        hi = [x for x in seq if x > pi]##选出大于第一个数的所有元素
        return lo, pi, hi
    
    def select(seq, k):
        lo, pi, hi = partition(seq)
        m = len(lo)#小于第一个数的元素有几个
        if m == k: return pi
        if m < k: return select(hi, k-m-1)
        return select(lo, k)
    
    if __name__ == '__main__':
        seq=(1,2,3,4,5)
        print(partition(seq))
        print(select(seq,3))

     

    展开全文
  • Python 中间值求TopK算法 算法思想以下以找出TopK 的最大值为例,最小值的可以自己修改一下下就可以重点就是找出这个中间值如何找出中间值结合代码和注释看 算法思想 首先我们要思考,我要做什么?解决什么问题? ...

    算法思想

    首先我们要思考,我要做什么?解决什么问题
    TopK问题,找出一组数据中的前K个最大值或者最小值,这个数据是否重复?要做去重处理?
    ok 我们明确我们做什么了 ,那介绍的python处理的topK 算法过程是怎么样的呢?
    ~~要找出前K个最大值最小值我们可以用排序来做,然后用切片去完事了 ~~ 如果用排序那就没必要引入topK 了,当数据强大的时候选取TopK 可以省略很多排序的计算,至于有多优化自己去思考下,就比如排列组合的C,A的区别,一个是抽取,一个是抽取并排列…

    以下以找出TopK 的最大值为例,最小值的可以自己修改一下下就可以

    介绍的算法思想是利用中间值,将数列分为三部分 ,
    【比中间值大的列表】,中间值,【比中间值小的列表】

    那么我们当比较
    【比中间值大的列表】的个数 == k
    的时候就可以得出前K个最大值了,因此

    重点就是找出这个中间值

    如何找出中间值

    以列表的第一个数开始为中间值,拆分为三部分
    if 【比中间值大的列表】的个数 == k:return 中间值 #程序出口,结束。

    if 【比中间值大的列表】的个数 < k
    ·····继续在【比中间值小的列表】找
    ·····K - 【比中间值大的列表】的个数 -1 个数
    (为什么要减一,1是前一次的中间值,分的三部分,前部分后部分都没有包含中间值,因此…)
    if 【比中间值大的列表】的个数 > k
    …也就是说比中间值大的列表比K还大,那就在这个列表中继续找就行

    结合代码和注释看

    ,如果要找最小值,只需要改一下就ok ,还可以设置一个布尔值的输入,来做前K个最大值最小值

    #2019 11 04
    #author 半斤地瓜烧
    #TopK 算法,找出序列中前K个最大值的
    
    #输入一个seq
    # 输出以seq[0]为中间值 划分的三个部分,中间值,比这个值大的seq ,比这个值小的seq,
    # 即splitNum,theBig,theSmall
    def Split_Seq(seq):
        splitNum = seq[0]
        seq = seq[1:]#两个部分都不包含中间值,因此切片去除seq[0]
        theBig = [x for x in seq if x >= splitNum]
        theSmall = [x for x in seq if x < splitNum]
        return splitNum,theBig,theSmall
    
    #找出中间值
    def topKNum(seq,k):
        splitNum, theBig, theSmall = Split_Seq(seq)
        theBigLen = len(theBig)
        
        if  k == theBigLen:
            return splitNum#出口,返回这个中间值,
        # 为什么不直接返回thebig?因为存在递归的原因thebig 不是在初始的seq找出来的
        #需要重新Split,即可,读者自己思考
    
        # 大值的列表中还未够K个数的情况,
        if k > theBigLen:
            return topKNum(theSmall,k-theBigLen-1)
    
        # 大值的列表中大于K个数的情况
        return topKNum(theBig,k)
    
    #由中间值找出TopK个值,<list>
    def getTopK(seq,k):
        
        return [i for i in seq if i > topKNum(seq, k)]
    
    
    if __name__ == '__main__':
        alist = [7, 3, 5, 1,885,234,2211,222,22, 2, 11, 2, 115]
        print("===为了验证,引入排序观看===", sorted(alist,reverse= True))
    
        print(getTopK(alist, 3))
    展开全文
  • python---的topk算法

    千次阅读 2017-10-26 10:32:09
    #! conding:utf-8 author = “hotpot” date = “2017/10/26 9:42”def quick_index(array, start, end): left, right = start, end key = array[left] while left while left < right and
    #! conding:utf-8
    

    author = “hotpot”
    date = “2017/10/26 9:42”

    def quick_index(array, start, end):
        left, right = start, end
        key = array[left]
        while left < right:
            while left < right and array[right] > key:
                right -= 1
            array[left] = array[right]
            while left < right and array[left] < key:
                left += 1
            array[right] = array[left]
    
        array[left] = key
        return left
    
    
    def min_num(array, m):
        start, end = 0, len(array) - 1
        index = quick_index(array, start, end)
        while index != m:
            if index < m:
                index = quick_index(array, index+1, end)
            else:
                index = quick_index(array, start, index)
    
        print(array[:m])
    
    if __name__ == '__main__':
        alist = [15,54, 26, 93, 17, 77, 31, 44, 55, 20]
    
        min_num(alist,  5)
    
    展开全文
  • 冒泡排序 插入排序 堆排序 归并排序 快速排序 TopK堆排序 没有一个排序算法是任何情况下都表现最好的。

    基础排序算法

    如果在面试中遇到排序算法,先问清楚数据的特点,结合具体的业务场景,多和面试官交流,先陈述思路,得到面试官肯定以后再编码
    没有一个排序算法是任何情况下都表现最好的。
    学习算法的可视化网站:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html

    常见排序算法对比
    在这里插入图片描述
    所有代码和思路以升序为例。

    冒泡排序

    思路:

    • 每一轮依次比较相邻的两个元素,如果前一个元素>后一个,则交换位置,保证未排定部分的最大元素置于数组末尾;
    • 重复上述步骤,直到第2个元素是前两个元素中最大的,排序结束;

    优化:
    通过flag标识已经有序的情况,提前停止排序。

    Python实现:

    class Solution:
        def sortArray(self, nums: List[int]) -> List[int]:
            if len(nums)<2:
                return nums
            
            flag = True
            n = len(nums)
            for i in range(n,0,-1):
                for j in range(1,i):
                    if nums[j-1]>nums[j]:
                        flag = False
                        nums[j-1],nums[j] = nums[j],nums[j-1]
                if flag:
                    break
            return nums
    

    复杂度分析:
    时间复杂度:O(n2),加上flag最优的情况即本身有序,O(n);
    空间复杂度:O(1),原地操作,不需要额外的空间。

    选择排序

    思路:

    • 每轮选出未排定部分中最小的元素,交换到未排定部分的开头,交换一次;

    Python实现:

    class Solution:
        def sortArray(self, nums: List[int]) -> List[int]:
            if len(nums)<2:
                return nums
            
            n = len(nums)
            for i in range(n):
                min_idx = i
                for j in range(i+1,n):
                    if nums[j]<nums[min_idx]:
                        min_idx = j
                nums[i],nums[min_idx] = nums[min_idx],nums[i]
    
            return nums
    

    复杂度分析:
    时间复杂度:O(n2);
    空间复杂度:O(1),原地操作,不需要额外的空间。

    优点: 交换次数最少
    在交换成本较高的排序任务中,可以使用选择排序。

    插入排序

    思路:

    • 保持当前元素左侧是排序后的数组,将当前元素插入到对应位置。

    Python实现:

    class Solution:
        def sortArray(self, nums: List[int]) -> List[int]:
            if len(nums)<2:
                return nums
            
            n = len(nums)
            for i in range(1,n):
                j = i 
                while j>0 and nums[j]<nums[j-1]:
                    nums[j],nums[j-1] = nums[j-1],nums[j]
                    j -= 1
    
            return nums
    

    复杂度分析:
    时间复杂度:O(n2),最好的情况即数组有序时,复杂度为O(n);
    空间复杂度:O(1),原地操作,不需要额外的空间。

    优化
    可以采用二分查找的方式来确定需要插入的位置

    优点:
    内层循环可以提前终止,因此插入排序在几乎有序的数组上表现良好,在短数组(每个元素离它最终排定的位置都不会太远)上表现也很好。

    归并排序

    思路:

    • 分而治之的思想,理解递归的好材料,递归时,只剩下一个元素或没有元素时返回;
    • 借助额外空间,合并两个有序数组,得到更长的有序数组。

    Python实现:

    class Solution:
        def sortArray(self, nums: List[int]) -> List[int]:
            if len(nums)<2:
                return nums
      
            self.mergesort(nums,0,len(nums)-1)
            return nums
        
        def merge(self,nums,left,mid,right):
            temp = []
            i = left
            j = mid+1
            while i<=mid and j<=right:
                if nums[i]<=nums[j]:
                    temp.append(nums[i])
                    i += 1
                else:
                    temp.append(nums[j])
                    j += 1
            while i<=mid:
                temp.append(nums[i])
                i += 1
            while j<=right:
                temp.append(nums[j])
                j += 1
            return temp
    
        def mergesort(self,nums,left,right):
            if left>=right:
                return
            mid = (left+right)//2
            self.mergesort(nums,left,mid)
            self.mergesort(nums,mid+1,right)
            temp = self.merge(nums,left,mid,right)
            for j in range(len(temp)):
                nums[left+j] = temp[j]
    

    复杂度分析:
    时间复杂度:确定的O(nlogn)
    空间复杂度:O(n),借助了额外空间,可以实现稳定排序

    缺点:
    需要额外的空间,元素来回复制;
    一般不用于内排序。

    优化:
    只开一个temp数组,避免频繁申请、释放内存。

    快速排序

    思路:

    • 每论都排定一个元素(主元pivot),然后递归地去排它左侧和右侧的部分,直到数组有序
      Tips:
      随机化选择切分元素,否则在输入数组是有序或逆序时,快速排序会非常慢;
      递归到规模充分小时,停止递归,直接用简单排序(如插入排序)。

    Python实现:

    ## 方法一:
    class Solution:
        def sortArray(self, nums: List[int]) -> List[int]:
            if len(nums)<=1:
                return nums
            
            def partition(left,right):
                pivot = nums[left]
                index = left
                for i in range(left+1,right+1):
                    if nums[i]<pivot:
                        index += 1
                        if i!=index:
                            nums[i],nums[index] = nums[index],nums[i]
                nums[left],nums[index] = nums[index],nums[left]
                return index
            
            def quicksort(low,high):
                if low<high:
                    idx = partition(low,high)
                    quicksort(low,idx-1)
                    quicksort(idx+1,high)
                return
    
            quicksort(0,len(nums)-1)
            return nums
    ## 方法二:
    def quickSort(self,nums,left,right):
            print(left,right,nums)
            if left>=right:
                return
            mid = (left+right)//2
            if nums[mid]<nums[left]:
                nums[mid],nums[left] = nums[left],nums[mid]
            if nums[right]<nums[left]:
                nums[right],nums[left] = nums[left],nums[right]
            if nums[mid]>nums[right]:
                nums[mid],nums[right] = nums[right],nums[mid]
            
            nums[mid],nums[right-1] = nums[right-1],nums[mid]
            #if right-left<=2:
            #    return
          
            pivot = nums[right-1]
            i = left
            j = right-1
            while i<j:
                i += 1
                j -= 1
                while nums[i]<pivot:
                    i += 1
                while nums[j]>pivot:
                    j -= 1
                if i<j:
                    nums[i],nums[j] = nums[j],nums[i]
                else:
                    break
    
            nums[i],nums[right-1] = nums[right-1],nums[i]
            print(nums)
            self.quickSort(nums,left,i-1)
            self.quickSort(nums,i+1,right)
    

    复杂度分析:
    时间复杂度:O(nlogn),最坏情况下O(n2)
    空间复杂度:O(logn)

    经典问题:TopK

    TopK 是面试常考的问题
    「力扣」第 215 题:数组中的第 K 个最大元素

    堆排序

    思路:
    堆是对选择排序的优化,通过把未排定部分构建成堆,可以实现O(logn)选择最大的元素。

    两个特性:

    1. 结构性:用数组表示的完全二叉树;
    2. 有序性:任一结点的关键字是其子树所有结点的最大值(或最小值)
      maxheap:最大堆,又叫大顶堆

    python:heapq模块

    Python实现:
    维护一个k大小的小顶堆,顶部就是第k个大的元素,如果是取最大的k个元素一般直接用大顶堆;
    heap数组大小设置为k+1,从下标为1开始存储元素,则下标为p的结点其左右子结点分别为2p/2p+1,其父节点为p//2。

    class Solution:
        def findKthLargest(self, nums: List[int], k: int) -> int:
            if not nums or len(nums)<k:
                return -1
            
            heap = [0 for _ in range(k+1)]
            for i in range(k):
                heap[i+1] = nums[i]
            
            ## build the heap
            for i in range(k//2,0,-1):
                self.percdown(i,k,heap)
            ## insert
            for i in range(k,len(nums)):
                if nums[i]>heap[1]:
                    heap[1] = nums[i]
                    self.percdown(1,k,heap)
            return heap[1]
    
        def percdown(self,i,k,heap):
            while i*2<=k:
                if i*2+1<=k and heap[i*2+1]<heap[i*2]:
                    Min = i*2+1
                else:
                   Min = i*2
                if heap[i]>heap[Min]:
                    heap[i],heap[Min] = heap[Min],heap[i]
                i = Min 
    

    复杂度分析:
    时间复杂度:O(nlogk)
    空间复杂度:O(k)

    空间复杂度与k相关,适用于海量的数据,不需要一次性完全读取。

    快速排序

    # TopK
    class Solution:
        def findKthLargest(self, nums: List[int], k: int) -> int:
            if len(nums)<k:
                return -1
            
            small = len(nums)-k
    
            def partition(left,right):
                pivot = nums[left]
                index = left
                for i in range(left+1,right+1):
                    if nums[i]<pivot:
                        index += 1
                        if i!=index:
                            nums[i],nums[index]=nums[index],nums[i]
                nums[left],nums[index] = nums[index],nums[left]
                if index==small:
                    return 
                elif index<small:
                    partition(index+1,right)
                else:
                    partition(left,index-1)
            
            partition(0,len(nums)-1)
            return nums[small]
    

    复杂度分析:
    时间复杂度:O(n),根据主定理计算可得;
    空间复杂度:O(logn),递归栈空间

    参考资料
    https://leetcode-cn.com/problems/sort-an-array/solution/dang-wo-tan-pai-xu-shi-wo-zai-tan-xie-shi-yao-by-s/
    https://leetcode-cn.com/problems/sort-an-array/solution/fu-xi-ji-chu-pai-xu-suan-fa-java-by-liweiwei1419/

    展开全文
  •  典型的Top K算法,还是在这篇文章里头有所阐述,详情请参见: 十一、从头到尾彻底解析Hash表 算法。    文中,给出的最终算法是:  第一步、先对这批海量数据预处理,在O(N)的时间内用Hash表完成 统计 ...
  • python数据结构与算法topk问题 问题描述:现有n个数,设计算法得到前k大的数 解决思路: 取列表前k个元素建立一个小根堆,堆顶就是目前第k大的数 依次向后遍历原列表,对于列表中的元素,如果小于堆顶,则忽略该...
  • Top K算法分析

    2019-04-22 15:30:00
    2019独角兽企业重金招聘Python工程师标准>>> ...
  • TopK算法及其实现

    2015-06-02 16:49:00
    2019独角兽企业重金招聘Python工程师标准>>> ...
  • top k算法的3种简单实现和比较

    千次阅读 2013-12-19 22:45:36
    top k算法是什么大家都明白,就不废话了,这里直接上代码。本人用python实现了3种常用算法,命名如下:  heap_bigk1,用堆排序对构建整个数据的大根堆,然后取前k个。  heap_bigk2 初始取前k个数据构建一个小根堆...
  • TopK算法及实现

    2013-12-16 09:24:00
    2019独角兽企业重金招聘Python工程师标准>>> ...
  • 算法要解决的问题是:在线性时间内找到一个无序序列中第 kk 大的数。(或许,该程序最重要的用途是找出中间值——也就是该序列完成排序后位于中间 (1+n)/2(1+n)/2 的元素值)。有趣的是,稍加改造,它也能找出所有...
  • 2019独角兽企业重金招聘Python工程师标准>>> ...
  • (5)例题: topK问题 问题: 现在有n个数, 设计算法找出前k大的数(k) 解决方法: 排序后切片 li . sort ( reverse = True ) [ : k - 1 ] 堆排序 import heapq def heapsort ( data , hp_...
  • 堆排序 - topk问题(python语言实现) 现在有n个数,设计算法得到前k⼤的数。(k<n) 解决思路: 1.取列表前k个元素建⽴⼀个⼩根堆。堆顶就是⽬前第k⼤的数。 2. 依次向后遍历原列表,对于列表中的元素,如果⼩于...
  • 堆基本概念堆排序是一个很重要的排序算法,它是高效率的排序算法,复杂度是O(nlogn),堆排序不仅是面试进场考的重点,而且在很多实践中的算法会用到它,比如经典的TopK算法、小顶堆用于实现优先级队列。堆排序是利用...
  • 另外还需要定义两个函数,其中一个函数来计算两个数据点之间的欧氏距离,另一个函数设置knn模型,即计算训练数据与测试数据之间的欧氏距离,然后根据距离来排序,提取top k近邻,并且计算邻居中出现次数最多的类。...
  • 数据从数据训练集下载地址下载,我选的是1MB版本的数据,大约10W+评分,9K+电影,600+用户。使用ratings.csv,格式为userId,movieId,评分,时间戳。步骤:1、解析CSV文件,构建训练集。2、计算两两物品分差平均值...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 134
精华内容 53
关键字:

topk算法python

python 订阅