从数组中找到topK的元素(序号)
问题:
在n个数中找出最大的k个数。
多次求min()或求max()
最简单的方法是对大小为k的数组进行n次求min计算(或者对大小为n的数组进行k次求max计算)最后能够找出最大k个数。复杂度是O(nk)。
代码:
def topK_mink(num_list,k):
topK=num_list[:k]
for i in range(k,len(num_list)):
topK_min=min(topK)
if num_list[i]>topK_min:
topK[topK.index(topK_min)]=num_list[i]
return topK
使用小根堆
维护一个大小为k的小根堆,从头到尾扫描n个数,如果当前数比堆顶大,替换堆顶,这样扫描到最后堆中保存的是最大的k个数。复杂度是O(nlogk)
代码:
import heapq
def topK_heapq(num_list,k):
array = []
for i in range(len(num_list)):
if len(array) < k:
heapq.heappush(array, num_list[i])
else:
array_min = array[0]
if num_list[i] > array_min:
heapq.heapreplace(array, num_list[i])
topK=array
return topK
使用大根堆
维护一个大小为n的大根堆,每次弹出堆顶元素,共弹出k次。复杂度O(klogn)
代码:略
快速选择BFPRT
借用快速排序中思想,在快排中每次用一个轴将数组划分为左右两部分,轴左边的数都小于轴,轴右边的数都大于轴,轴所在的位置和排好序后的位置相同。这里只要找到第k大的数作为轴进行划分,那么就找到了最大的k个数。期望复杂度是:O(n)
代码:
def topK_partition(arr,k):
def partition(num_list,left,right,k):
flag=num_list[left]
i=left
j=right
while i<j:
#print(flag,i,j,num_list)
if num_list[i]>flag:
i+=1
elif num_list[j]<flag:
j-=1
else:
if num_list[i]==num_list[j]:
j-=1
num_list[i],num_list[j]=num_list[j],num_list[i]
#print(flag,num_list)
if i<k:
return partition(num_list,i+1,right,k)
if i>k:
return partition(num_list,left,i-1,k)
return num_list[:k]
return partition(arr[:],0,len(random_list)-1,k)
测试代码:
import numpy as np
import time
def judge(ans,k1):
for i in ans:
if i-k1<0:
return False
return True
k=1000
n=25000
random_list=[np.random.randint(n*0.5) for i in range(n)]
real_ans=sorted(random_list,reverse=True)[:k+1]
k1=real_ans[-1]
t1=time.time()
ans=topK_heapq(random_list,k)
t2=time.time()
print(judge(ans,k1),t2-t1)
t1=time.time()
ans=topK_partition(random_list,k)
t2=time.time()
print(judge(ans,k1),t2-t1)
t1=time.time()
ans=topK_mink(random_list,k)
t2=time.time()
print(judge(ans,k1),t2-t1)
结果:
topK_mink()没有任何优势
topK_partition()的运行时间不稳定
topK_heapq()运行时间稳定
虽然期望复杂度topK_partition()优于topK_heapq(),但是topK_partition()计算开销比topK_heapq()多。
当n小时,用topK_heapq()比topK_partition()好
当n大,k小时,topK_heapq()用时也较短。
当n大,k大时(n>10,000,000),用topK_partition()。
从数组中找到topK的元素(序号)的更多相关文章
- 在未排序的数组中找到第 k 个最大的元素
在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 输出: 5 ...
- PHP从数组中找到指定元素的位置
群里有人问,有个数组五个元素 分为1到5 现在要求 循环找出3元素的索引,怎么做性能才是最高. 我不知道哪个性能最高,但是我想提出可以用多种方式进行查找,然后进行比较选择. 我想,最简单最基础的 应 ...
- 【一起刷LeetCode】在未排序的数组中找到第 k 个最大的元素
题目描述 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 ...
- 《程序员代码面试指南》第八章 数组和矩阵问题 在数组中找到出现次数大于N/K 的数
题目 在数组中找到出现次数大于N/K 的数 java代码 package com.lizhouwei.chapter8; import java.util.ArrayList; import java ...
- python经典面试算法题4.1:如何找出数组中唯一的重复元素
本题目摘自<Python程序员面试算法宝典>,我会每天做一道这本书上的题目,并分享出来,统一放在我博客内,收集在一个分类中. [百度面试题] 难度系数:⭐⭐⭐ 考察频率:⭐⭐⭐⭐ 题目描述 ...
- 【Matlab开发】matlab删除数组中符合条件的元素与散点图绘制
[Matlab开发]matlab删除数组中符合条件的元素与散点图绘制 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ matlab删除数组中符合条件的元素 如 ...
- Js判断数组中是否存在某个元素
Js判断数组中是否存在某个元素 方法一:indexOf(item,start); Item:要查找的值:start:可选的整数参数,缺省则从起始位子开始查找. indexOf();返回元素在数组中的位 ...
- JavaScript从数组中删除指定值元素的方法
本文实例讲述了JavaScript从数组中删除指定值元素的方法.分享给大家供大家参考.具体分析如下: 下面的代码使用了两种方式删除数组的元素,第一种定义一个单独的函数,第二种为Array对象定义了一个 ...
- [java]删除数组中的某一个元素
package org.company.project.test; import java.util.Arrays; import java.util.Scanner; public class Ar ...
随机推荐
- 推荐中的多任务学习-ESMM
本文将介绍阿里发表在 SIGIR'18 的论文ESMM<Entire Space Multi-Task Model: An Effective Approach for Estimating Po ...
- 简单聊一聊JS中的循环引用及问题
本文主要从 JS 中为什么会出现循环引用,垃圾回收策略中引用计数为什么有很大的问题,以及循环引用时的对象在使用 JSON.stringify 时为什么会报错,怎样解决这个问题简单谈谈自己的一些理解. ...
- 【转】面向GC的Java编程
Java程序员在编码过程中通常不需要考虑内存问题,JVM经过高度优化的GC机制大部分情况下都能够很好地处理堆(Heap)的清理问题.以至于许多Java程序员认为,我只需要关心何时创建对象,而回收对象, ...
- Jquery实现图片管理
这里实现的是一个图片的在线管理,类似于网络相册的图片管理. 效果图如下: 文件结构如下图: style2.css文件内容如下: @charset "utf-8"; *{;; } i ...
- Nginx的一理解(2)
1.静态HTTP服务器 首先,Nginx是一个HTTP服务器,可以将服务器上的静态文件(如HTML.图片)通过HTTP协议展现给客户端. 配置:
- VSCode前端 插件
https://www.cnblogs.com/karthuslorin/p/8577224.html
- 多个github账号时,本地配置ssh-key
由于需要,申请了多个github账号,但是都是在同一台电脑上操作,原来只有一个账号进行ssh操作时,推送没有遇到什么问题,现在有多个账号了,推送的时候就有点懵逼了,下面是根据网上的资料来进行多个账号, ...
- python类型-序列-元组
元组是一种不可变类型,元组可用作一个字典的key. 1.创建一个元组并进行赋值 atuple = (123, 'abc', ('inner', 'tuple'), 7-9j) 2.访问元组中的值 元组 ...
- 开发工具篇:Git和Github
开发工具篇:Git和Github Git是什么? Git是目前世界上最先进的分布式版本控制系统.工作原理 / 流程: Workspace:工作区 Index / Stage:暂存区 Repositor ...
- python实例:自动爬取豆瓣读书短评,分析短评内容
思路: 1.打开书本“更多”短评,复制链接 2.脚本分析链接,通过获取短评数,计算出页码数 3.通过页码数,循环爬取当页短评 4.短评写入到txt文本 5.读取txt文本,处理文本,输出出现频率最高的 ...