无序数组求第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 ...
随机推荐
- java 实现加密算法(在网上看的,保存)
import java.util.ArrayList; import java.util.List; /** * DES加密/解密 * * @Copyright Copyr ...
- vue_VueRouter 路由_路由器管理n个路由_并向路由组件传递数据_新标签路由_编程式路由导航
路由:就是一个 key 与 value 的映射关系.key 就是 pathh 前台路由的 value 是 Component 组件对象 后台路由的 value 是一个 回调函数 普通链接: 会发送请求 ...
- js 检查登录态方法封装(闭包、状态缓存)
前端页面开发时,经常需要异步校验登录态,每次都重新copy之前写的方法,比较繁琐不好维护,固将登录态校验封装成一个js. (function(){ //登录状态 1 登录态有效 2 登录态无效 3 请 ...
- 分析一个MySQL并发事务示例
小结: 1. https://mp.weixin.qq.com/s/hdDl95a6ayVtCoEc3RiLwQ 分析一个MySQL并发事务示例 性能与架构 1月12日 MySQL实战45讲 从原 ...
- poj1164
#include<iostream> using namespace std; ][]; ][]; int roomnum; int maxroom; int m,n; typedef s ...
- hexo建站报错解决记录
安装某主题依赖 nodejieba 库,该库又依赖 windows-build-tools 和 node-gyp git bash shell 下 cnpm install -g windows-bu ...
- Spark入门到精通--(第八节)环境搭建(Hadoop搭建)
上一节把Centos的集群免密码ssh登陆搭建完成,这一节主要讲一下Hadoop的环境搭建. Hadoop下载安装 下载官网的Hadoop 2.4.1的软件包.http://hadoop.apache ...
- 允许浏览器下载exe.config文件
进入系统目录 %windir%\System32\inetsrv\config\ 编辑IIS配置文件 applicationHost.config 找到如下行 <requestFiltering ...
- linux内核态和用户态的信号量
在Linux的内核态和用户态都有信号量,使用也不同,简单记录一下. 1> 内核信号量,由内核控制路径使用.内核信号量是struct semaphore类型的对象,它在中定义struct sema ...
- Java面试题和解答(二)
1.字符流和字节流的区别,使用场景是什么,相关类有哪些 http://blog.csdn.net/zj8692286/article/details/126507312.线程安全的概念,实现线程安全的 ...