从数组中找到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 ...
随机推荐
- Faceted project metadata file "/.settings/org.eclipse.wst.common.project.facet.core.xml" could not be read
转载自 https://blog.csdn.net/qing_gee/article/details/79397052 Eclipse启动后项目报了下图这个错误,说是org.eclipse.wst.c ...
- Tensorflow内存暴涨问题
1.目前只总结出两条 创建saver实例saver = tf.train.Saver()放在循环外面 不循环初始化变量 sess.run(tf.global_variables_initializer ...
- LoopBox 用于包装循环的盒子
/******************************************************* * * 作者:朱皖苏 * 创建日期:20180608 * 说明:此文件只包含一个类,具 ...
- python报错:not supported between instances of 'str' and 'int'
not supported between instances of 'str' and 'int' : 意思就是字符串不能和int类型的数值比较
- Broken Necklace 坏掉的项链 USACO 模拟(易错)
1004: 1.1.4Broken Necklace 坏掉的项链 时间限制: 1 Sec 内存限制: 128 MB提交: 11 解决: 9[提交] [状态] [讨论版] [命题人:外部导入] 题目 ...
- ORM执行原生SQL语句
# 1.connectionfrom django.db import connection, connections cursor = connection.cursor() # cursor = ...
- kafka(一)-为什么选择kafka
作为开发人员,我们在选择一个框架或者工具时,我们都需要考虑些什么,我们不是头脑发热,一拍脑袋就它了,我们首先要认清这个框架或工具的作用是什么,能给我们带来什么样的好处,同时也要考虑带来什么样的负面结果 ...
- (转)宽字节编码类型的XSS
今晚又看了一遍PKAV-心上的瘦子写的xss腾讯系列的例子,收获挺大的,其中对宽字节注入有了更深的了解,又查找了一些相关的资料,整理一下,以备以后查阅 参考文档: http://book.2cto.c ...
- (ES6)JavaScript中面向对象类的实现
在ES5中,我们就知道JS是不支持面向对象的,所以用函数模拟了一个构造函数来实现类的.那么在ES6中,在ES5的原理基础上,将代码书写更为简单,明了. 一.怎样用ES6创建类?首先看一看例子: cla ...
- MySQL5.6绿色版安装
1.下载 MySQL绿色版安装需下载好三个文件 (1).MySQL5.6版本离线安装包 (2).Microsoft Visual C++ (3).Microsoft .NET Framework 1. ...