无序数组求第k大/第k小的数
根据http://www.cnblogs.com/zhjp11/archive/2010/02/26/1674227.html
博客中所总结的7种解法,我挑了其中的解法3和解法6进行了实现。
解法3: 利用快速排序的思想,从数组S中随机找出一个元素X,把数组分为两部分Sa和Sb。Sa中的元素大于等于X,Sb中元素小于X。这时有两种情况:
1.
Sa中元素的个数小于k,则Sb中的第k-|Sa|个元素即为第k大数;
2.
Sa中元素的个数大于等于k,则返回Sa中的第k大数。时间复杂度近似为O(n)
#include<stdio.h>
#include<string.h>
int par(int a[],int l,int r){
int x=a[l];
while(l<r){
while(l<r&&a[r]<=x) --r;
a[l]=a[r];
while(l<r&&a[l]>=x) ++l;
a[r]=a[l];
}
a[l]=x;
return l;
}
int search(int a[],int l,int r,int k){
if(l<=r){
int p = par(a,l,r);
if(p-l+==k) return p;
else if(p-l+<k){
return search(a,p+,r,k-(p-l+));
}else{
return search(a,l,p-,k);
}
}
}
int main(){
int n,k;
int a[];
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
printf("%d\n",a[search(a,,n,k)]);
return ;
}
解法6:维护一个k大小的最小堆,对于数组中的每一个元素判断与堆顶的大小,若堆顶较大,则不管,否则,弹出堆顶,将当前值插入到堆中。时间复杂度O(n * logk)
注意:这里要求第k大的数,所以要构建的是小顶堆,并且只有当新进来的数大于堆顶也就是目前k个数里最小的数时,才有可能是第k个大的数,才将其加入堆。
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
void heapAdd(int a[],int i,int num){
a[i]=num;
for(int j=i>>;j&&i&&a[i]<a[j];i=j,j>>=)
swap(a[i],a[j]);
}
void heapDown(int a[],int i,int n){
for(int j=i<<;j<=n;i=j,j<<=){
if(j+<=n&&a[j+]<a[j]) j++;
if(a[i]>a[j]) swap(a[i],a[j]);
}
}
int a[],n,k,b[];
int main(){
scanf("%d%d",&n,&k);
int cnt=;
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
if(cnt<k){
heapAdd(b,++cnt,a[i]);
}else{
if(b[]<a[i]){
b[]=a[i];
heapDown(b,,k);
}
}
}
printf("%d\n",b[]);
return ;
}
如果要求的是第k小的数,则把相应的判断条件改一下就可以了
无序数组求第k大/第k小的数的更多相关文章
- 无序数组求第K大的数
问题描述 无序数组求第K大的数,其中K从1开始算. 例如:[0,3,1,8,5,2]这个数组,第2大的数是5 OJ可参考:LeetCode_0215_KthLargestElementInAnArra ...
- 求一无序数组中第n大的数字 - 快速选择算法
逛别人博客的时候,偶然看到这一算法题,顺便用C++实现了一下. 最朴素的解法就是先对数组进行排序,返回第n个数即可.. 下面代码中用的是快速选择算法(不晓得这名字对不对) #include <v ...
- 无序数组中第Kth大的数
题目:找出无序数组中第Kth大的数,如{63,45,33,21},第2大的数45. 输入: 第一行输入无序数组,第二行输入K值. 该是内推滴滴打车时(2017.8.26)的第二题,也是<剑指of ...
- 从长度为 M 的无序数组中,找出N个最小的数
从长度为 M 的无序数组中,找出 N个最小的数 在一组长度为 n 的无序的数组中,取最小的 m个数(m < n), 要求时间复杂度 O(m * n) 网易有道面试题 const minTopK ...
- uva 12356 Army Buddies 树状数组解法 树状数组求加和恰为k的最小项号 难度:1
Nlogonia is fighting a ruthless war against the neighboring country of Cubiconia. The Chief General ...
- 数据结构2 静态区间第K大/第K小
给定数组$A[1...N]$, 区间$[L,R]$中第$K$大/小的数的指将$A[L...R]$中的数从大到小/从小到大排序后的第$K$个. "静态"指的是不带修改. 这个问题有多 ...
- 1005E1 Median on Segments (Permutations Edition) 【思维+无序数组求中位数】
题目:戳这里 百度之星初赛原题:戳这里 题意:n个不同的数,求中位数为m的区间有多少个. 解题思路: 此题的中位数就是个数为奇数的数组中,小于m的数和大于m的数一样多,个数为偶数的数组中,小于m的数比 ...
- Ping pong(树状数组求序列中比某个位置上的数小的数字个数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2492 Ping pong Time Limit: 2000/1000 MS (Java/Others) ...
- hdu5057 分块处理,当数值大于数据范围时树状数组 真是巧 将大数据分为小数据来处理
这题说的给了100000个数有100000次操作 询问 L和R 区间内 在D位上为P的个数,用树状数组存 要开[10][10][100000]的int 开不了但是能开 这么大的unsign short ...
随机推荐
- XVIII Open Cup named after E.V. Pankratiev. Ukrainian Grand Prix
A. Accommodation Plan 对于已知的$K$个点,离它们距离都不超过$L$的点在树上是一个连通块,考虑在每种方案对应的离$1$最近的点统计. 即对于每个点$x$,统计离它距离不超过$L ...
- Lesnoe Ozero 2016. BSUIR Open 2016 Finals
A. Street magic 数位DP,设$f[i][j][k]$表示从低到高考虑$x$的后$i$位,$x$和$m$大小关系为$j$,和$n$大小关系为$k$的方案数. #include<cs ...
- 一分钟掌握位运算符—与(&)、非(~)、或(|)、异或(^)
第一个版本: 位运算符的计算主要用在二进制中. 实际开发中也经常会遇到需要用到这些运算符的时候,同时这些运算符也被作为基础的面试笔试题. 所以了解这些运算符对程序员来说是十分必要的. 于此,记录下 ...
- vue_过滤器: 对要显示的数据进行特定格式化后再显示
过滤器 对要显示的数据进行特定格式化后再显示 并未改变原本的数据,可是产生新的对应的数据 <!DOCTYPE html> <html lang="en"> ...
- CSS 使用absolute 是<div>居中
<style> .col-center-block { position: absolute; top: 50%; ...
- 个人作业4——alpha阶段个人总结
一.个人总结 类型 具体技能和面试问题 现在的回答(大三) 语言 拿手的计算机语言(偏web前端,PC/Mobile App) java 语言 拿手的计算机语言(偏后端,数据处理,网站后台,机器学习等 ...
- request之额外路径
谈到额外路径 ,首先要明白映射路径,映射路径是servlet处理的路径,在web.xml中配置.比如配置一个/emp的映射路径,意味着客户端可以通过http:+项目路径+/emp访问服务器的项目,而所 ...
- robotframe中使用report,设置路径带有时间戳
1.打开C:\Python27\Lib\site-packages\robotide\contrib\testrunner,找到testrunner.py. 修改代码块def _create_te ...
- 【C++】满二叉树问题
/* 给出一棵满二叉树的先序遍历,有两种节点:字母节点(A-Z,无重复)和空节点(#).要求这个树的中序遍历.输出中序遍历时不需要输出#. 满二叉树的层数n满足1<=n<=5. Sampl ...
- 《HTTP - 跨域》
本文参考 HTTP访问控制(CORS) 一:什么是跨域? - 所谓跨域, 是浏览器为了保护网站安全而建立的一种保护策略,既浏览器的同源策略. - 意味着使用这些API的Web应用程序只能从加载应用程序 ...