(转:http://www.cnblogs.com/luxiaoxun/archive/2012/08/06/2624799.html)

寻找N个数中最大的K个数,本质上就是寻找最大的K个数中最小的那个,也就是第K大的数。

可以使用二分搜索的策略来寻找N个数中的第K大的数。对于一个给定的数p,可以在O(N)的时间复杂度内找出所有不小于p的数。

寻找第k大的元素:

#include <iostream>
using namespace std; //快速排序的划分函数
int partition(int a[],int l,int r)
{
int i,j,x,temp;
i = l;
j = r+1;
x = a[l];
//将>=x的元素换到左边区域
//将<=x的元素换到右边区域
while (1)
{
while(a[++i] > x);
while(a[--j] < x);
if(i >= j) break;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
a[l] = a[j];
a[j] = x;
return j;
} //随机划分函数
int random_partition(int a[],int l,int r)
{
int i = l+rand()%(r-l+1);//生产随机数
int temp = a[i];
a[i] = a[l];
a[l] = temp;
return partition(a,l,r);//调用划分函数
} //线性寻找第k大的数
int random_select(int a[],int l,int r,int k)
{
int i,j;
if (l == r) //递归结束
{
return a[l];
}
i = random_partition(a,l,r);//划分
j = i-l+1;
if(k == j) //递归结束,找到第K大的数
return a[i];
if(k < j)
{
return random_select(a,l,i-1,k);//递归调用,在前面部分查找第K大的数
}
else
return random_select(a,i+1,r,k-j);//递归调用,在后面部分查找第K大的数
} int main()
{
int a[]={1,2,3,4,6,6,7,8,10,10}; cout<<random_select(a,0,9,1)<<endl;
cout<<random_select(a,0,9,5)<<endl;
return 0;
}

如果所有N个数都是正整数,且它们的取值范围不太大,可以考虑申请空间,记录每个整数出现的次数,然后再从大到小取最大的K个。比如,所有整数都在(0, MAXN)区间中的话,利用一个数组count[MAXN]来记录每个整数出现的个数(count[i]表示整数i在所有整数中出现的个数)。只需要扫描一遍就可以得到count数组。然后,寻找第K大的元素:

for(sumCount = 0, v = MAXN-1; v >= 0; v--)
{
sumCount += count[v];
if(sumCount >= K)
break;
}
return v;

极端情况下,如果N个整数各不相同,我们甚至只需要一个bit来存储这个整数是否存在(bit位为1或为0),这样使用的空间可以大大压缩。

当然也可以使用像计数排序、桶排序等这些以O(N)的时间排序算法也可以寻找第K大的数,但这也是以空间换时间为代价的。

实际情况下,并不一定保证所有元素都是正整数,且取值范围不太大。上面的方法仍然可以推广使用。如果N个数中最大的数Vmax,最小的Vmin,我们可以把这个区间[Vmax,Vmin]分成M块,每个小区间的跨度为d=(Vmax-Vmin)/M,即[Vmin,Vmin+d],[Vmin+d,Vmin+2d]......然后,扫描一遍所有元素,统计各个小区间中的元素个数,就可以知道第K大的元素在哪一个小区间。然后,再在那个小区间中找第K大的数(此时这个小区间中,第K大的数可能就是第T大的数了,这个T和每个小区间的个数有关)。我们需要找一个尽量大的M,但M的取值受到内存的限制。

O(N)的时间寻找最大的K个数的更多相关文章

  1. 算法系列:寻找最大的 K 个数

    Copyright © 1900-2016, NORYES, All Rights Reserved. http://www.cnblogs.com/noryes/ 欢迎转载,请保留此版权声明. -- ...

  2. 第2章 数字之魅——寻找最大的K个数

    寻找最大的K个数 问题描述 在面试中,有下面的问答: 问:有很多个无序的数,我们姑且假定它们各不相等,怎么选出其中最大的若干个数呢? 答:可以这样写:int array[100] …… 问:好,如果有 ...

  3. 03寻找最小的k个数

    题目描述:查找最小的k个元素         题目:输入n个整数,输出其中最小的k个.         例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4. 1:最简单 ...

  4. 算法练习:寻找最小的k个数

    参考July的文章:http://blog.csdn.net/v_JULY_v/article/details/6370650 寻找最小的k个数题目描述:查找最小的k个元素题目:输入n个整数,输出其中 ...

  5. 编程之美2.5:寻找最大的K个数

    编程之美2.5:寻找最大的K个数 引申:寻找第k大的数: 方法一: // 选择第k大的数(通过改进快速排序来实现) public static void SelectShort(int[] array ...

  6. 寻找最大的k个数问题

    这是编程之美书第2.5节的一道题目. 各种解法: 解法一,用nlgn复杂度的排序算法对数组进行从大到小排序,取前K个.但这方法做了两件不必要做的事:它对想得到的K个数进行了排序,对不想得到的n-K个数 ...

  7. 【编程之美】2.5 寻找最大的k个数

    有若干个互不相等的无序的数,怎么选出其中最大的k个数. 我自己的方案:因为学过找第k大数的O(N)算法,所以第一反应就是找第K大的数.然后把所有大于等于第k大的数取出来. 写这个知道算法的代码都花了2 ...

  8. 寻找最大的K个数(下)

    接着昨天的写,里面的代码包含昨天的 #include <iostream> using namespace std; #define N 50 //初始化数组 , , , , , , , ...

  9. 算法笔记_035:寻找最小的k个数(Java)

    目录 1 问题描述 2 解决方案 2.1 全部排序法 2.2 部分排序法 2.3 用堆代替数组法 2.4线性选择算法   1 问题描述 有n个整数,请找出其中最小的k个数,要求时间复杂度尽可能低. 2 ...

随机推荐

  1. scala 模式匹配详解 2 scala里是怎么实现的?

    在这篇martin和另外两位模式匹配领域专家的论文里说了模式匹配的几种实现方式,以及scala是选择哪种方式来实现的.http://lampwww.epfl.ch/~emir/written/Matc ...

  2. WPS 2019 多个sheet表拆分成独立的excel文件

    参考: https://www.cnblogs.com/hackxiyu/p/8945975.html 场景:将多个sheet表拆分成独立的excel文件 一.安装VB工具: 默认情况下:wps -- ...

  3. 电子书阅读(epub) --- calibre

    https://calibre-ebook.com/download   calibre https://www.fosshub.com/Calibre.html   win 64 bit calib ...

  4. Kotlin入门第一课:从对比Java开始

    1. 介绍 今年初,甲骨文再次对谷歌所谓的安卓侵权使用Java提起诉讼,要求后者赔偿高达90亿美元.随后便传出谷歌因此计划将主力语言切换到苹果主导的Swift,不过这事后来没了跟进. 但谷歌在这两天的 ...

  5. .Net Windows Service(服务) 调试安装及System.Timers.Timer 使用

    Windows Service(服务)  是运行在后台的进程 1.VS建立 Windows 服务(.NET Framework) 2.添加Timer 双击Service1.cs可以拖控件(System ...

  6. 各种可再发行组件包Redistributable及framework 下载

    安装包名称 版本号 下载地址 Visual C++ 2005 Redistributable Package (x64)   下载 Visual C++ Redistributable Package ...

  7. [No000016A]CSS常用三种选择器

    1.HTML Tag p{color:red;} 2.id #myid{color:red;} 3.class .myclass{color:red;} CSS常用文本样式属性 color font- ...

  8. Elasticsearch全文检索实战小结

    一.项目概述 这是一个被我称之为“没有枪.没有炮,硬着头皮自己造”的项目.项目是和其它公司合作的三个核心模块开发. 使用ES的目的是: 1).采集数据.网站数据清洗后存入ES: 2).对外提供精确检索 ...

  9. webstorm 智能提示忽略大小写

    setting-Editor-General-Code Completion里的 Case sensitive completion: 可以设置只第一个字母敏感.完全敏感或者不敏感. 选择none.. ...

  10. NULL - AUTO_INCREMENT

    http://dev.mysql.com/doc/refman/5.7/en/create-table.html Data Types and Attributes for Columns data_ ...