求第k小的数 O(n)复杂度
思路:利用快速排序的思想,把数组递归划分成两部分。设划分为x,数组左边是小于等于x,右边大于x。关键在于寻找一个最优的划分,经过 Blum 、 Floyd 、 Pratt 、 Rivest 、 Tarjan五位大牛的研究总结,提出了BFPRT 算法(也就是中位数的中位数算法),利用中位数的中位数算法得到的数作为划分可以实现最优划分--在最差情况下能实现O(n)复杂度。接下来考虑可能出现许多重复的数,假设数组中所有的数全部相同,每次划分之后都是当前区间的右端点,即会退化到O(n^2)复杂度。我也是没处理好重复元素,导致TLE多次。一个比较好的办法就是改写partion算法,设每次划分的标准数为x,将所有的与x相等的元素集中到一起,例如数组a[]={4,4,4,2,1,4,5,6},x=4,划分之后应该是{1,2,4,4,4,4,5,6}。很容易能得到等于x的元素的个数cnt,接下来就是决策的处理:
设当前划分的下标为ind.
如果ind+1==k,直接返回a[ind]
如果ind+1<k,递归进入[ind+1,r)的区间继续寻找答案
接下来就是处理重复元素的关键步骤,如果ind+1>k
可分成两种情况:
1、k位于重复元素[ind+1-cnt+1,ind+1]之中,直接返回a[ind],直接结束程序.
2、k位于所有重复元素之前,则应该丢弃重复元素,递归进入[l,ind-cnt+1)的区间继续寻找答案
当然,这题n<=10^6,直接用sort以O(nlgn)也能过。
AC代码:
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1e6+5;
int a[maxn];
int n,k;
inline int findmid(int l,int r){ //中位数的中位数
if(r-l<=5) return (l+r)/2;
for(int i=0;i<(r-l)/5;++i){
sort(a+l+i*5,a+l+i*5+5);
swap(a[l+i],a[l+i*5+2]);
}
return findmid(l,l+(r-l)/5);
}
int partion(int l,int r,int &p){ //改进版partion
int h=findmid(l,r);
swap(a[h],a[r-1]);
p=0;
int ind=l-1;
for(int i=l;i<r-1;++i){
if(a[i]==a[r-1]) ++p;
if(a[i]<=a[r-1])
swap(a[++ind],a[i]);
}
++p;
swap(a[++ind],a[r-1]);
int i=l,j=ind-1;
while(i<j){
if(a[i]==a[ind]){
while(a[j]==a[ind]) --j;
if(i<j){
swap(a[i],a[j]);
--j;
}
}
++i;
}
return ind;
}
int solve(int l,int r){
int p=0;
int ind=partion(l,r,p);
if(ind+1==k) return a[ind];
if(ind+1>k){
if(ind+1-p+1<=k) return a[ind];
else return solve(l,ind-p+1);
}
if(ind+1<k) return solve(ind+1,r);
}
int main(){
scanf("%d%d",&n,&k);
for(int i=0;i<n;++i) scanf("%d",&a[i]);
printf("%d\n",solve(0,n));
return 0;
}
如有不当之处欢迎指出!
求第k小的数 O(n)复杂度的更多相关文章
- 求第k小的数
题目链接:第k个数 题意:求n个数中第k小的数 题解: //由快速排序算法演变而来的快速选择算法 #include<iostream> using namespace std; const ...
- *HDU2852 树状数组(求第K小的数)
KiKi's K-Number Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- [LeetCode] 4. Median of Two Sorted Arrays(想法题/求第k小的数)
传送门 Description There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the m ...
- 基于快速排序思想partition查找第K大的数或者第K小的数。
快速排序 下面是之前实现过的快速排序的代码. function quickSort(a,left,right){ if(left==right)return; let key=partition(a, ...
- 最快效率求出乱序数组中第k小的数
题目:以尽量高的效率求出一个乱序数组中按数值顺序的第k 的元素值 思路:这里很容易想到直接排序然后顺序查找,可以使用效率较高的快排,但是它的时间复杂度是O(nlgn),我们这里可以用一种简便的方法,不 ...
- 无序数组求第k大/第k小的数
根据http://www.cnblogs.com/zhjp11/archive/2010/02/26/1674227.html 博客中所总结的7种解法,我挑了其中的解法3和解法6进行了实现. 解法3: ...
- 树状数组求第k小的元素
int find_kth(int k) { int ans = 0,cnt = 0; for (int i = 20;i >= 0;i--) //这里的20适当的取值,与MAX_VAL有关,一般 ...
- [LeetCode] Find K-th Smallest Pair Distance 找第K小的数对儿距离
Given an integer array, return the k-th smallest distance among all the pairs. The distance of a pai ...
- #7 找出数组中第k小的数
「HW面试题」 [题目] 给定一个整数数组,如何快速地求出该数组中第k小的数.假如数组为[4,0,1,0,2,3],那么第三小的元素是1 [题目分析] 这道题涉及整数列表排序问题,直接使用sort方法 ...
随机推荐
- MySQL两大存储引擎InnoDB与MyISAM
1.InnoDB存储引擎 MySQL5.5中InnoDB成为默认的存储引擎.InnoDB是事务型存储引擎,被设计用来处理大量的短期事务.它的性能和自动崩溃恢复特性,使得它在非事务场景中也很流行. 所以 ...
- Python用户输入和代码注释
一.用户输入 若你安装的是Python3.x版本,当你在Python IDLE(编辑器) 中输入以下代码: name = input('用户名:') print('Hello',name) 保存并执行 ...
- Oracle Start With关键字
Oracle Start With关键字 前言 旨在记录一些Oracle使用中遇到的各种各样的问题. 同时希望能帮到和我遇到同样问题的人. Start With (树查询) 问题描述: 在数据库中, ...
- 基于jsmpeg库下使用ffmpeg创建视频流连接websocket中继器传输视频并播放
这个功能的基本工作是这样的: 1.使用node运行jsmpeg库下的websocket-relay.js文件,这个文件的作用是创建一个websocket视频传输中继器 2.运行ffmpeg,将输出发送 ...
- java判断网页的编码格式
在爬取内容时,遇到乱码问题.故需对网页内容编码格式做判断,方式大体分为三种:一.从header标签中获取Content-Type=#Charset:二.从meta标签中获取Content-Type=# ...
- tomcat部署最佳实践(一)
Tomcat部署最佳实践 标签: linux 笔者Q:972581034 交流群:605799367.有任何疑问可与笔者或加群交流 tomcat是玩web软件必会技能之一,今天我给大家介绍一下tomc ...
- linux下iptables配置模板
linux下iptables配置模板 # Flush all policy iptables -F iptables -X iptables -Z iptables -t nat -F iptable ...
- SSD写入放大问题[转]
原文地址:http://blog.csdn.net/cywosp/article/details/29812433 之前在SSD(Solid State Drive)上设计并实现缓存系统用于存储数据块 ...
- CF585E. Present for Vitalik the Philatelist [容斥原理 !]
CF585E. Present for Vitalik the Philatelist 题意:\(n \le 5*10^5\) 数列 \(2 \le a_i \le 10^7\),对于每个数\(a\) ...
- IDEA如何创建及配置Web项目(多图)
正文之前 在学习Java Web时,第一个遇到的问题就是如何创建或配置Web项目了,今天,就用IntelliJ IDEA 来进行Web项目配置: 创建Web项目 配置web项目 正文 创建Web项目 ...