zoukankan      html  css  js  c++  java
  • 关于“最小的K个数”问题

      从一堆无序的数中(共n个数)找到最小的K个数,这也算是一道比较经典的题目了,关于这道题目的解法,一般有几种:

    方法1:先对所有的数据进行排序,然后直接找出前K个数来,即最小的K个数。时间复杂度为O(N*logN)。

    方法2:采用类似快排的思想,只要找到第K小的数值的位置的话,那么数组中的前K个数值一定是最小的K个数,但是这K个数不一定是排好序的,关于找到第K个小的数值的方法卡参考我之前的文章:http://www.cnblogs.com/wangkundentisy/p/8810077.html

    当然,也可以参考《剑指offer(第二版)》面试题40。这种方法的期望时间复杂度为O(N),但是适用于大多数情况;最坏情况下时间复杂度可达到O(N^2)。

    方法3:利用一个大顶堆,具体过程如下:

      选取数据中前K个数(或者任意K个数)构成一个大顶堆,这个堆的根节点就是这K个数中的最大值,然后从剩余的n-K个数中依次找一个数与根节点的数比较,如果比根节点的数大的话,则跳过;如果比根节点的数小的话,就把根节点删除,并把这个数值加入到这个堆中,然后再把这个堆调整成大顶推,重复上述过程,直到比较完剩余的n-k个数。

    这种方法的时间复杂度为O(N*logK)。

    方法4:利用堆排序的思想,建立一个大小为n的小顶堆,由于小顶堆的顶点一定是n个数中的最小值,所以每次删除根节点,然后在调整堆,重复K次,就能找到最小的K个值了。(与堆排序的过程一致)这种算法的时间复杂度为O(K*logN)。

    ==================================================================================================分割线=================================================

    1.当n的值不是很大时,以上几种方法的性能相差并不是很大,通常方法2用的比较多。 

    2.那么当n很大的时候,方法1和方法2就不适用了。通常采用方法3。(关于海量数据处理的问题可参考july的博客:https://blog.csdn.net/v_july_v/article/details/7382693)那么,为什么不能采用方法4呢?以下是个人的一些见解:

    在n非常大的时候,数据需要存到硬盘上,而K相对却很小,采用方法3的话,可以在内存上轻易维护大小为K的堆的情况下,在减少磁盘I/O上会有一定的优势,因为每个元素只需要被读取一次。即方法3只需将大小为K的堆写入内存,而方法4需要将所有的n个数据写入内存,相比而言方法3对内存要求更小,更具有优势。所以,在有限的资源下,海量数据处理问题,通常采用方法3.

  • 相关阅读:
    【CSS】4种CSS方法设置元素垂直水平居中
    js数据类型:引用和5种基本数据类型
    iOS——CALayer的shadow无效问题
    iOS——自定义Segue实现总结
    iOS动画
    iOS——Command-Line 查看当前SDK版本并修改默认SDK版本
    iOS——Swift开发中的单例设计模式(摘译,非原创)
    Windows Phone 8 解锁提示IpOverUsbSvc问题——IpOverUsbEnum返回No connected partners found解决方案
    Windows 8.1 开发过程中遇到的小问题(2)
    Windows 8.1 开发过程中遇到的小问题
  • 原文地址:https://www.cnblogs.com/wangkundentisy/p/8821142.html
Copyright © 2011-2022 走看看