从数组中找到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 ...
随机推荐
- java基础之----redi分布式锁
最近项目中,用到了redis分布式锁,使用过程有些心得,所以希望分享给大家. 首先我们意识里要知道分布锁有哪些? 分布式锁一般分三种,基于数据库的乐观锁,基于redis的分布式锁,基于zookeper ...
- java 多线程 快速入门
------------恢复内容开始------------ java 多线程 快速入门 1. 进程和线程 什么是进程? 进程是正在运行的程序它是线程的集合 进程中一定有一个主线程 一个操作系统可以有 ...
- placeHolder和defaultValue的区别
placeHolder和defaultValue的区别 (1)placeHolder用于提示用户,它不与后端进行交互. (2)defaultValue则是与后端交互时的默认值. 举例说明:在Selec ...
- spring boot介绍
spring boot简介 1.spring boot是spring家族中的一个全新的框架,它用来简化spring应用程序的创建和开发过程,也可以说spring boot能简化我们之前采用ssm框架进 ...
- 阿里CTR预估:用户行为长序列建模
本文将介绍Alibaba发表在KDD'19 的论文<Practice on Long Sequential User Behavior Modeling for Click-Through Ra ...
- 自动将本地文件保存到GitHub
前言 只有光头才能变强. 文本已收录至我的GitHub精选文章,欢迎Star:https://github.com/ZhongFuCheng3y/3y 这篇文章主要讲讲如何自动将本地文件保存到GitH ...
- Java 成员变量与局部变量
成员变量与局部变量的区别 什么是局部变量.什么是成员变量: 局部变量:在方法内部的变量 形参:在方法签名中定义的变量. 方法局部变量:在方法内部定义的变量. 代码块局部变量:在代码块内定义的变量. 成 ...
- P1850 换教室 期望dp
P1850 换教室 题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有 2n2n 节课程安排在 nn 个时间段上.在第 ii(1 \leq ...
- swagger生成错误问题 汇总解决
Unable to render this definition The provided definition does not specify a valid version field. Ple ...
- hadoop各版本hadoop.dll和winutils.exe缺少这两个文件
1.1 缺少winutils.exeCould not locate executable null \bin\winutils.exe in the hadoop binaries1.2 缺少had ...