(转: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. Math.ceil()、Math.floor()和Math.round()

    下面来介绍将小数值舍入为整数的几个方法:Math.ceil().Math.floor()和Math.round(). 这三个方法分别遵循下列舍入规则: Math.ceil()执行向上舍入,即它总是将数 ...

  2. TSPL学习笔记(1)

    扩展语法(Syntactic extensions) 扩展语法就是通过核心语法或已经定义的扩展语法创建一种新的语法模式. Scheme核心语法模式包括: 顶层定义 常量 变量 过程应用 '(quote ...

  3. mui---开发直播APP

    因项目需要,需要开发一款直播类的APP,采用的技术是MUI,找到的参考文档如下: http://ask.dcloud.net.cn/article/13416

  4. TIScript Graphics

    $(#main_frame).paintContent = function(gfx) { gfx.pushLayer(#background-area); gfx.translate(0.5,0.5 ...

  5. HTTP协议中GET和POST方法的区别

    转载 通常的理解 w3schools关于这个问题的解答:HTTP 方法:GET 对比 POST 列出了一般的理解: 方法 GET POST 后退按钮/刷新 无害 数据会被重新提交(浏览器应该告知用户数 ...

  6. java 中的闭包

    原文地址:https://sylvanassun.github.io/2017/07/30/2017-07-30-JavaClosure/ 1.自由变量: function Add(y) { retu ...

  7. 评估分类器性能的度量,像混淆矩阵、ROC、AUC等

    评估分类器性能的度量,像混淆矩阵.ROC.AUC等 内容概要¶ 模型评估的目的及一般评估流程 分类准确率的用处及其限制 混淆矩阵(confusion matrix)是如何表示一个分类器的性能 混淆矩阵 ...

  8. Analytics.js简介

    analytics.js JavaScript代码段是一种可用于衡量用户与您网站的互动情况的全新方式.它与之前的跟踪代码ga.js类似,但为开发者自定义实现方案提供了更大的灵活性. analytics ...

  9. js中if语句的几种优化代码写法

    UglifyJS是一个对javascript进行压缩和美化的工具,在它的文档说明中,我看到了几种关于if语句优化的方法. 一.使用常见的三元操作符 复制代码 代码如下: if (foo) bar(); ...

  10. datagrid---columns列

    { field:"city", //字段名,从后台传来的要一致 title:"城市",//列的标题文字. width:,//列的宽度 formatter:fun ...