关闭

【Python】求数组(list)中最大的X个数,不递归,尽可能减少代码量

标签: PythonTopK最值算法排序
4319人阅读 评论(1) 收藏 举报
分类:

在Python中求数组中最大值、最小值直接有max(list),min(list)这个没什么好说的, 就算不知道有这个封装好的方法,直接用C语言那种求一个数组的最大值、最小值也是没问题的。然而,求数组(list)中最大的X个数,这就麻烦大了,这涉及了所谓的TOP-K算法。网上对于TOP-K算法的解决主要有快速排序与堆的处理,个人认为这都不是好方法。这两个方法,时间复杂度、空间复杂度绝对是传世经典,然而,其中的代码过于复杂,一个小小的求数组(list)中最大的X个数,这么简单的功能,写这么长的代码。

个人认为一来不好记,二来不好扩展。下面推荐一种自己写的,一种时间复杂度最好情况为O(n),最坏情况为O(k^2n)的求数组(list)中最大的X个数,空间复杂度为k的算法。当然,这不是重点,如下图,一个千万级别的数组,3.8s能够找到最大的10个数,我认为这种耗时,完全在可操作范围,最重要的,我认为代码短是重点。


具体代码如下,我们先用Python的洗牌算法,搞一个1-100乱序的数组,需要找到最大的10个数,显然是91-100,然而此数组是乱序的,所以怎么找到其中的91-100就是本文研究的问题:

#-*-coding:utf-8-*-
import random
#产生一个1-100的数组,并且打乱顺序
k=10;
arraylist=[];
for i in range(1,101):
    arraylist.append(i);
random.shuffle(arraylist);
print arraylist;

#求其中的最大的10个数
maxlist=[];#最大值数组(TopK数组),也就是最后的结果存放地方
for i in range(0,k):#先将目标数组前10个数放到TopK数组
    maxlist.append(arraylist[i]);
maxlist.sort(cmp=None, key=None, reverse=True);#对这个存有10个最大值数组(TopK数组)进行降序排序

for i in range(k,len(arraylist)):#对目标数组之后的数字
    if arraylist[i]>maxlist[k-1]:#如果你大于最大值数组(TopK数组)的最后一个数,因为进行过排序,也就是其中的最小值
        maxlist.pop();#那最大值数组(TopK数组)最后一个数,因为进行过排序,也就是其中的最小值滚出
        maxlist.append(arraylist[i]);#那你这个数就进入这个最大值数组(TopK数组)
        maxlist.sort(cmp=None, key=None, reverse=True);#之后,我们再对最大值数组(TopK数组)进行降序排序

print maxlist;

最终的运行结果如下:


上面打印的,确实是打乱了的一个从1-100的数组,

最终找出来的数确实是100-91。

而且上面对于最大值数组(TopK数组)进行降序排序也不是每一个数都触发,因此耗时是处于接受范围的。关键是,对比于网上的什么推排序、快速排序,反正我数据结构不好,记不住,难以理解~更关键的是,这些算法用到递归就好了。


0
0
查看评论

numpy找出array中的最大值,最小值

在python中利用numpy创建一个array, 然后我们想获取array的最大值,最小值。可以使用一下方法: 一、创建数组 这样就可以获得一个array的最大值和最小值了。 并且可以利用np.where(np.max(a))来获得最大值,最小值的行和列数。 二、python下对文件的操作...
  • qq_18293213
  • qq_18293213
  • 2017-04-14 21:23
  • 13502

如何寻找数组中的最大值和最小值

以下五种解法可以寻找到数组中的最大值和最小值; 1)问题分解法。     把本题看做两个独立的问题,而非一个问题,所以,每次分别找出最小值和最大值即可,此时,一共需要遍历两次数组,比较次数为2N次;(N表示数组的长度)  2)取单元素法。   ...
  • JohnLee_chun
  • JohnLee_chun
  • 2016-09-14 22:27
  • 5714

飘逸的python - 大数据TopK问题的quick select解法

TopK问题,即寻找最大的K个数,这个问题非常常见,比如从1千万搜索记录中找出最热门的10个关键词. 方法一: 先排序,然后截取前k个数. 时间复杂度:O(n*logn)+O(k)=O(n*logn)。 方法二: 最小堆. 维护容量为k的最小堆.根据最小堆性质,堆顶一定是最小的,...
  • u010180339
  • u010180339
  • 2014-11-21 18:17
  • 4516

Python 数据结构与算法——选取算法(TopK)

该算法要解决的问题是:在线性时间内找到一个无序序列中第 kk 大的数。(或许,该程序最重要的用途是找出中间值——也就是该序列完成排序后位于中间 (1+n)/2(1+n)/2 的元素值)。有趣的是,稍加改造,它也能找出所有比目标元素小的元素。def partition(seq): pi, se...
  • lanchunhui
  • lanchunhui
  • 2016-03-23 10:22
  • 1035

海量数据中找出前k大数(topk问题)

前两天面试3面学长问我的这个问题(想说TEG的3个面试学长都是好和蔼,希望能完成最后一面,各方面原因造成我无比想去鹅场的心已经按捺不住了),这个问题还是建立最小堆比较好一些。         先拿10000个数建堆,然后一次添加剩余元素,如果大于堆顶的数...
  • suibianshen2012
  • suibianshen2012
  • 2016-07-23 10:59
  • 4643

python使用heapq实现小顶堆(TopK大)/大顶堆(BtmK小)

参考链接https://www.coder4.com/archives/3844求一个数列前K大数的问题经常会遇到,在程序中一般用小顶堆可以解决,下面的代码是使用python的heapq实现的小顶堆示例代码: # !/usr/bin/env python # -*- coding:gb...
  • tanghaiyu777
  • tanghaiyu777
  • 2017-02-16 19:16
  • 985

Python 妙用heapq

小顶堆求TopK大 大顶堆求BtmK小 题外话Python有一个内置的模块,heapq标准的封装了最小堆的算法实现。下面看两个不错的应用。小顶堆(求TopK大)话说需求是这样的: 定长的序列,求出TopK大的数据。import heapq import randomclass TopkHeap(ob...
  • Marksinoberg
  • Marksinoberg
  • 2016-10-04 16:26
  • 7478

海量数据处理 - 10亿个数中找出最大的10000个数(top K问题)

前两天面试3面学长问我的这个问题(想说TEG的3个面试学长都是好和蔼,希望能完成最后一面,各方面原因造成我无比想去鹅场的心已经按捺不住了),这个问题还是建立最小堆比较好一些。         先拿10000个数建堆,然后一次添加剩余元素,如果大于堆顶的数(1...
  • zyq522376829
  • zyq522376829
  • 2015-08-16 00:09
  • 17196

基于快速排序的TOPK算法

类似于快速排序,首先选择一个划分元,如果这个划分元的序号index刚好等于k,那么这个划分元以及左边的数,刚好组成了top-k small data;如果index>k, 那top-k small data在index的左边,那么就继续递归从index-1和数中选取top-k.如果index ...
  • fanzitao
  • fanzitao
  • 2012-05-30 17:37
  • 3508

求一个整数数组的最大元素,用递归方法实现

求一个整数数组的最大元素,用递归方法实现 public static int maxNum(int[] a, int start){ int len = a.length-start; if(len==1) return a[start]; else { return ...
  • shuiziliu1025
  • shuiziliu1025
  • 2016-09-12 16:15
  • 1020
    个人资料
    • 访问:1977633次
    • 积分:26100
    • 等级:
    • 排名:第272名
    • 原创:751篇
    • 转载:0篇
    • 译文:0篇
    • 评论:379条
    文章分类
    【备注】博文GIF动画的录制方法
    先用屏幕录制软件Freez Screen Video Capture录制屏幕,再把得到的AVI,利用GIF Movie Gear转化成GIF
    【友情链接】亲笔小说