关于在指定区间求第k小的数,求高效率算法

针对给定数列及多个查询需求,如何快速找出指定区间内第K小的元素?本文介绍了一种利用快排变形解决该问题的方法,并提出采用伴随数组优化查询效率,实现一次排序多次查找。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、问题来源


给定一个整数数列a[1..n],其中每个元素都不相同,你的程序要能回答一组格式为Q (i , j , k)的查询,Q(i, j ,k)的意思是“在a[i..j]中第k小的数是多少?”  
例如令 a = {1, 5, 2, 6, 3, 7, 4},查询格式为Q (2 , 5 , 3),数列段a[2..5] = {5, 2, 6, 3},第3小的数是5,所以答案是5。

第一行包括一个正整数n,代表数列的总长度,还有一个数m,代表有m个查询。n、m满足:1≤n≤100 000,1≤m≤5 000。  

第二行有n个数,代表数列的元素,所有数都不相同,而且不会超过10^9  

接下来有m行,每行三个整数i、j、k,代表一次查询,i、j、k满足:1≤i≤j≤n, 1≤k≤j−i+1。  

关于这个问题可能已经讨论了很多次,但是我用快排的变形还是超时,希望能看更高效的算法



二、解答

(1)、如果是进行1次查询的话,可以采用快速排序的变种,时间复杂度为O(N),但是有5000次的话 效率就不太高了。



(2)采用伴随数组的方法。排序复杂为O(NlogN),每次查找的复杂度为O(N).

详细的讲解可参考

http://blog.youkuaiyun.com/v_JULY_v/article/details/6452100

采用后伴随数组的好处就是,为了对此查询,“一次排序,多次查找”!伴随数组的实现挺简单的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值