zoukankan      html  css  js  c++  java
  • topK问题

    概述

    在N个乱序数字中查找第K大的数字,时间复杂度可以减小至O(N).
    可能存在的限制条件:
    要求时间和空间消耗最小、海量数据、待排序的数据可能是浮点型等。

    方法

    方法一

    • 对所有元素进行排序,之后取出前K个元素,时间复杂度高,不提倡。 *
      思路:使用快排,选择排序,堆排序。
      时间复杂度:排序复杂度nlogn,最后要访问第K个元素,因此是O(n*logn)+O(K)=O(n*logn)
      特点:需要对全部元素进行排序,K=1时,时间复杂度也为O(n*logn)。

    方法二

    • 只需要对前K个元素排序,剩下N-K个元素不需要排序,时间复杂度高,不提倡。 *
      思路:使用选择排序 或 冒泡排序, 进行K此选择,可得到第K大的数。
      时间复杂度:每一次大循环遍历复杂度是n,共遍历K次,因此是O(n*k)
    def selectionSort(arr, k):
        length = len(arr)
        minIndex = 0
        for i in range(length):
            minIndex = i
            for j in range(i+1,length):
                if arr[j] < arr[minIndex]:
                    minIndex = j
    
            arr[i], arr[minIndex] = arr[minIndex], arr[i]
            if i == k:
                return arr[:k]
    
        return arr
    
    arr = [3,4,9,2,1,0,-10]
    print(selectionSort(arr, 3))
    
    

    方法三

    • 不对前K个数排序+不对N-K个数排序 *
      思路:寻找第K个大元素
      具体方法:使用类似快排,执行一次快排后,每次只选择一部分继续执行快排,直到找到第K个大元素为止,此时这个元素在数组位置后面的元素即所求。
      时间复杂度:
    • 若随机选取枢纽,线性期望时间O(N)
    • 若选取数组的“中位数的中位数”作为枢纽,最坏情况下的时间复杂度O(N)
      利用快排的思想,从数组S中随机找出一个元素X,把数组分为两部分Sa和Sb。Sa中的元素大于等于X,Sb中元素小于X。这时有两种情况:
    1. Sa中元素的个数小于k,则Sb中的第k-|Sa|个元素即为第k大数;
    2. Sa中元素的个数大于等于k,则返回Sa中的第k大数。
      利用快排的partion思想T(n) = 2T(n/2) + O(1) 时间复杂度为O(n)
      该方法只有当我们可以修改输入的数组时可用,位于数组左边的k个数字就是最小的k个数字(但这k个数字不一定是排序的),位于第k个数右边的数字都比第k个数字大。
  • 相关阅读:
    转 Linux查看版本信息及CPU内核、型号等
    freeswitch ODBC error: ODBC NOT AVAILABLE!
    asterisk 命令
    Freeswitch mod 安装
    数据库压缩备份
    IEnumreable的使用小结
    新的Layout布局系统
    前台网站开发手记
    容器服务是如何在高速增长下保持高可用性的
    Kubernetes问题排查流程
  • 原文地址:https://www.cnblogs.com/ocean1100/p/9790231.html
Copyright © 2011-2022 走看看