K选择问题
来源:互联网 发布:姚明nba前几场比赛数据 编辑:程序博客网 时间:2024/06/05 12:41
从N个数当中选出第k个最大者。 最简单的两种算法:
算法A1:排序-->返回k位置的数。时间复杂度
O(N^2)
算法A2:先读入前k个数-->排序-->逐个读入其余-->插入/丢掉。时间复杂度
O(KN)
K=N/2 (上取整) 时,两者复杂度都是O(N^2)
新解法一、用优先队列(堆)解决选择问题
优先队列基础知识
- 优先队列基本模型
- 优先队列的简单实现
方法a,链表:表头插入-->遍历链表删除最小元。时间复杂度O(1)+O(N)
方法b,二叉查找树。时间复杂度O(logN)
- 优先队列更好的实现方案:二叉堆(简称堆)
a.二叉堆的结构性质
堆:完全填满的二叉树。底层元素从左到右填入。(完全二叉树)
完全二叉树,高h与节点数N的关系
N = 2^h ~ 2^(h+1) - 1h = O(logN)
完全二叉树非常规律-->可以用数组表示完全二叉树
位置i的元素-->左儿子[2i],右儿子(2i+1),父亲(i/2)下取整
b.堆序性质
堆序性质(heap-order property):让操作快速执行的性质
在一个堆中,每一个子节点X的父亲中的关键字小于等于X的关键字,根节点除外。
c.基本的堆操作(见数据结构与算法分析P153)
用优先队列解决选择问题
算法A3:
将N个元素读入数组,对数组应用buildHeap
算法。执行k次deleteMin
操作。
buildHeap
最坏情况用时O(N)
每次deleteMin
用时O(logN)
k
次deleteMin
-->用时O(klogN + N)
算法A4:
用简单方法A2,但用堆buildHeap
来实现前k个数,耗时O(k)-->检测新元素是否进入O(1)-->必要时删除旧插入新O(logk)-->总时间O( k + (N - k)logk )=O( Nlogk )
新解法二、用快速排序解决选择问题(快速选择)
算法A5:
选取S中一个元素作为枢纽元v,将集合S-{v}分割成S1和S2,就像快速排序那样
如果k <= |S1|,那么第k个最小元素必然在S1中。在这种情况下,返回QuickSelect(S1, k)
。
如果k = 1 + |S1|,那么枢纽元素就是第k个最小元素,即找到,直接返回它。
否则,这第k个最小元素就在S2中,即S2中的第(k - |S1| - 1)个最小元素,我们递归调用并返回QuickSelect(S2, k - |S1| - 1)
。
此算法的平均运行时间为O(N)
。
复杂度比较
在我自己的项目中,k=1或2.所以采用算法a2或者a4比较好。a2代码量小,果断采用。
- K选择问题
- 选择问题-第k小元素
- 选择问题-第k小元素
- 选择问题——N个数中取第K个最大
- 选择问题——选取第K小元素
- 选择问题(找出第k小的数)
- 选择问题(查找第k小元素)
- 用PriorityQueue解决选择最小的K个数问题
- 选择问题(第k小元素)(分治法)
- Top k问题(线性时间选择算法)
- 选择问题-输出第k大的数
- 动态规划之最大k乘积,编辑距离,k好数,节点选择,背包问题
- 算法导论-选择数组中第K小的数(选择问题)
- 选择问题——N个数中选择第K个最大数
- k-means如何选择合适的k?
- k近邻算法中k值得选择
- 选择问题(求N个数中第k个最大者)
- 分治思想解,选择问题(从给定数组中找第K小的元素)
- 第三方支付“躺着赚钱”的时代开始终结
- Java二维数组计算集合(上下左右左斜右斜)
- 1436 [CA1009]The root of the equation
- RC积分(如果叫做低通也行) 俗语
- DQN_tensorflow 源码解读
- K选择问题
- Huge Matrix 扫描
- 硬件访问服务4之Android硬件访问服务框架及系统函数全详细实现
- 搜素-Q
- spring入门(注解实现Bean的定义)
- ubuntu opencv多版本控制
- 两个队列实现一个栈
- [一天几个linux命令] 改变文件所属用户组,所有者 chgrp chown
- SAP HANA Odata报错500 Internal Server Error