最大K个数问题的Python版解法总结


Posted in Python onJune 16, 2016

TopK问题,即寻找最大的K个数,这个问题非常常见,比如从1千万搜索记录中找出最热门的10个关键词.
方法一:
先排序,然后截取前k个数.
时间复杂度:O(n*logn)+O(k)=O(n*logn)。
这种方式比较简单粗暴,提一下便是。

方法二:最大堆

我们可以创建一个大小为K的数据容器来存储最小的K个数,然后遍历整个数组,将每个数字和容器中的最大数进行比较,如果这个数大于容器中的最大值,则继续遍历,否则用这个数字替换掉容器中的最大值。这个方法的理解也十分简单,至于容器的选择,很多人第一反应便是最大堆,但是python中最大堆如何实现呢?我们可以借助实现了最小堆的heapq库,因为在一个数组中,每个数取反,则最大数变成了最小数,整个数字的顺序发生了变化,所以可以给数组的每个数字取反,然后借助最小堆,最后返回结果的时候再取反就可以了,代码如下:

import heapq
def get_least_numbers_big_data(self, alist, k):
  max_heap = []
  length = len(alist)
  if not alist or k <= 0 or k > length:
    return
  k = k - 1
  for ele in alist:
    ele = -ele
    if len(max_heap) <= k:
      heapq.heappush(max_heap, ele)
    else:
      heapq.heappushpop(max_heap, ele)

  return map(lambda x:-x, max_heap)


if __name__ == "__main__":
  l = [1, 9, 2, 4, 7, 6, 3]
  min_k = get_least_numbers_big_data(l, 3)

方法三:quick select

quick select算法.其实就类似于快排.不同地方在于quick select每趟只需要往一个方向走.
时间复杂度:O(n).

def qselect(A,k): 
  if len(A)<k:return A 
  pivot = A[-1] 
  right = [pivot] + [x for x in A[:-1] if x>=pivot] 
  rlen = len(right) 
  if rlen==k: 
    return right 
  if rlen>k: 
    return qselect(right, k) 
  else: 
    left = [x for x in A[:-1] if x<pivot] 
    return qselect(left, k-rlen) + right 
 
for i in range(1, 10): 
  print qselect([11,8,4,1,5,2,7,9], i)
Python 相关文章推荐
python 多线程应用介绍
Dec 19 Python
python通过pil为png图片填充上背景颜色的方法
Mar 17 Python
Python守护进程和脚本单例运行详解
Jan 06 Python
python中字符串类型json操作的注意事项
May 02 Python
python数据结构之链表详解
Sep 12 Python
Django使用Mysql数据库已经存在的数据表方法
May 27 Python
python学习开发mock接口
Apr 28 Python
python 实现GUI(图形用户界面)编程详解
Jul 17 Python
flask 实现token机制的示例代码
Nov 07 Python
PyCharm取消波浪线、下划线和中划线的实现
Mar 03 Python
Python的scikit-image模块实例讲解
Dec 30 Python
Python 装饰器(decorator)常用的创建方式及解析
Apr 24 Python
Python中的多行注释文档编写风格汇总
Jun 16 #Python
Python构造自定义方法来美化字典结构输出的示例
Jun 16 #Python
浅谈Python中chr、unichr、ord字符函数之间的对比
Jun 16 #Python
详解Python中 __get__和__getattr__和__getattribute__的区别
Jun 16 #Python
Python利用带权重随机数解决抽奖和游戏爆装备问题
Jun 16 #Python
Python黑魔法@property装饰器的使用技巧解析
Jun 16 #Python
Python实现类似jQuery使用中的链式调用的示例
Jun 16 #Python
You might like
如何分别全角和半角以避免乱码
2006/10/09 PHP
PHP 程序员也要学会使用“异常”
2009/06/16 PHP
11个PHP 分页脚本推荐
2011/08/15 PHP
php switch语句多个值匹配同一代码块应用示例
2014/07/29 PHP
php生成gif动画的方法
2015/11/05 PHP
菜单效果
2006/10/14 Javascript
简单的Jquery全选功能
2013/11/07 Javascript
修改或扩展jQuery原生方法的代码实例
2015/01/13 Javascript
分享有关jQuery中animate、slide、fade等动画的连续触发、滞后反复执行的bug
2016/01/10 Javascript
微信小程序 闭包写法详细介绍
2016/12/14 Javascript
vue v-model表单控件绑定详解
2017/05/17 Javascript
Javascript实现从小到大的数组转换成二叉搜索树
2017/06/13 Javascript
javascript 中事件冒泡和事件捕获机制的详解
2017/09/01 Javascript
Vue 2.5 Level E 发布了: 新功能特性一览
2017/10/24 Javascript
fetch 使用及如何接收JS传值
2017/11/11 Javascript
JS设计模式之策略模式概念与用法分析
2018/02/05 Javascript
Vue Echarts实现可视化世界地图代码实例
2019/05/07 Javascript
解决layer弹出层的内容页点击按钮跳转到新的页面问题
2019/09/14 Javascript
详解Vue中的MVVM原理和实现方法
2020/07/15 Javascript
Javascript中Math.max和Math.max.apply的区别和用法详解
2020/08/24 Javascript
Django中STATIC_ROOT和STATIC_URL及STATICFILES_DIRS浅析
2018/05/08 Python
对TensorFlow的assign赋值用法详解
2018/07/30 Python
对python opencv 添加文字 cv2.putText 的各参数介绍
2018/12/05 Python
Python3.5内置模块之random模块用法实例分析
2019/04/26 Python
css3 自定义字体font-face使用介绍
2014/05/14 HTML / CSS
HTML5 解决苹果手机不能自动播放音乐问题
2017/12/27 HTML / CSS
AJAX应用和传统Web应用有什么不同
2013/08/24 面试题
咖啡馆创业计划书
2014/01/26 职场文书
调研座谈会发言材料
2014/08/23 职场文书
基层干部群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
县政府办公室领导班子对照检查材料思想汇报
2014/09/28 职场文书
大学运动会加油稿
2015/07/22 职场文书
2015年音乐教学工作总结
2015/07/22 职场文书
礼仪培训心得体会
2016/01/22 职场文书
2016年青少年禁毒宣传教育活动总结(学校)
2016/04/05 职场文书
广告文案的撰写技巧(实用干货)
2019/08/23 职场文书