C++--问题19--查找数组前K个最小值的算法

C++--问题19--查找数组前K个最小值的算法


解决这个问题的初思路,都能想到先排序,然后前K个最小值的算法就出来了。排序用快速和堆排序,有几种具体的方法如下:
 

1.  快速排序,找前K

     对数组进行排序,然后前K个元素就是需要查找的元素,排序的方法可以采用快速排序。
但是我们知道在快速排序中如果已经是有序的数组,采用快速排序的时间复杂度是O(N^2)。
     为了解决这种问题,有两种解决办法,
(1)随机选择一个数组值pivot作为基准,将数组分为S1 <=  pivot 和 S2 > pivot;
(2)采用随机选择三个元素,然后取中间值作为基准,就能避免快速算法的最差时间复杂度。

2.先划分再比较K与S1个数的大小,为了省去不必要的排序,再快排找前K

        既然是选择前K个对象,那么就没必要对所有的对象进行排序,可以采用快速选择的思想获得前K个对象。
    (1)首先采用快速排序的集合划分方法划分集合:S1,pivot,S2,满足S1 <=  pivot 和 S2 > pivot;
    (2)然后比较K是否小于S1的个数, 如果小于,则直接对S1进行快速排序 ,如果K的个数超过S1,那么对S2进行快速排序;
    (3)排序完成之后,取数组的前K个元素就是数组的前K个最小值。
 这种实现方法肯定比第一种的全快速排序要更快速。
 

 3.创建K次的最小堆

      将数组转换为最小堆的情况,根据最小堆的特性,第一个元素肯定就是数组中的最小值,这时候我们可以将元素保存起来,然后将最后一个元素提升到第一个元素,重新构建最小堆,这样进行K次的最小堆创建,就找到了前K个最小值。这是运用了最小堆的特性,实质上是 最小堆的删除实现方法 。这种算法的好处是实现了数组的原地排序,并不需要额外的内存空间。
 

4.创建最大堆

       这种思想有点类似桶排序。
      (1)给定一个K个大小的数组b,然后复制数组a中的前K个数到数组b中;
      (2)将这K个数当成数组a的前K个最小值,对数组b创建最大堆;
      (3)这时候再去比较数组a中的其他元素,如果其他元素小于数组b的最大值(堆顶),则将堆顶的值进行替换,并重新创建最大堆。
      (4)这样遍历一次数组就找到了前K个最小元素。这种方法运用了额外的内存空间,特别当选择的K值比较大时,这种方法有待于权衡一下。
         这种方法对于 海量数据来说是有较好的作用 ,对于海量数据不能全部存放在内存中,这时候创建一个较小的数组空间,然后创建最大堆,从硬盘中读取其他的数据,进而实现前K个数据的查找。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值