手撕算法系列——2. top-k问题

    这道题也是很经典的面试题了,因为很多互联网公司要处理海量数据,从海量数据中筛选第k大(小)的数据成为了很常见的问题,这道题也因为解法众多而一直受到热议。下面假定问题是要从n个不同大小的数据寻找第k大的元素,即有k-1个元素大于它。

(1)解法一——简单粗暴排序

    这个解法不用多说了,如果使用基于比较的排序,则平均时间复杂度为O(nlogn),如果n很大的话,这个时间复杂度是难以接受的,而且问题只需要寻找k个最大的元素,而这个解法将所有元素排序了一遍,相当不划算。

(2)解法二——每次剔除一个最大的元素,直至第k个

    这个解法也很容易实现,寻找数组中最大的元素的时间复杂度是线性的,因此这个算法的时间复杂度为O(nk),如果k<<n,这个算法的时间复杂度已经大大优于解法一了,但是如果k也很大,这个算法还是相当消耗时间的。

(3)解法三——用最小堆实现

    top-k问题可以理解为寻找k个最大的元素里面最小的一个,因此可以利用堆的性质,即最小堆的root结点的data域是堆中最小的。先建立一个结点数固定为k的最小堆,遍历整个数组的元素,将其与堆的根节点值进行比较,如果遇到比根节点值更大的元素,则更新根节点值为该值,并将堆重新排序;如果遇到的值比根节点值小,则直接pass掉。这样遍历完整个数组后,根节点的值便是第k大的值了。这个算法的可视化执行过程可以在Ben Frede

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值