题目地址:http://ac.jobdu.com/problem.php?pid=1371

题目描述:

输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。

输入:

每个测试案例包括2行:

第一行为2个整数n,k(1<=n,k<=200000),表示数组的长度。

第二行包含n个整数,表示这n个数,数组中的数的范围是[0,1000 000 000]。

输出:

对应每个测试案例,输出最小的k个数,并按从小到大顺序打印。

样例输入:
8 4
4 5 1 6 2 7 3 8
样例输出:
1 2 3 4

我们可以先创建一个大小为k的数据容器来存储最小的k个数字。接下来我们每次从输入的n个整数中读入一个数。如果容器中已有的数字少于k个,则直接把这次读入的整数放入容器之中;如果容器中已有k个数字了,也就是容器已满,此时我们不能再插入新的数字而只能替换已有的数字。我们找出这已有的k个数中最大值,然和拿这次待插入的整数和这个最大值进行比较。如果待插入的值比当前已有的最大值小,则用这个数替换替换当前已有的最大值;如果带插入的值比当前已有的最大值还要大,那么这个数不可能是最小的k个整数之一,因为我们容器内已经有k个数字比它小了,于是我们可以抛弃这个整数。

因此当容器满了之后,我们要做三件事情:一是在k个整数中找到最大数,二是有可能在这个容器中删除最大数,三是可能要插入一个新的数字,并保证k个整数依然是排序的。如果我们用一个二叉树来实现这个数据容器,那么我们能在O(logk)时间内实现这三步操作。因此对于n个输入数字而言,总的时间效率就是O(nlogk)

下面是用堆排序解决该问题的代码:

#include <stdio.h>

void HeapSort(int Array[], int len);
void BuildMaxHeap(int Array[], int len);
void ShiftDown(int Array[], int index, int len);
void Swap(int *m, int *n); int main(void){
int len;
int k;
int Array[200000];
int i; while (scanf("%d %d", &len, &k) != EOF){ //读入数据个数
for (i=1; i<=len; ++i) //读入数据
scanf("%d", &Array[i]);
BuildMaxHeap(Array, k);
for (i=k + 1; i <= len; ++i){
if (Array[i] < Array[1]){
Array[1] = Array[i];
ShiftDown(Array, 1, k);
}
}
HeapSort(Array, k);
for (i=1; i<=k; ++i){
printf("%d", Array[i]);
if (i != k)
putchar (' ');
}
putchar ('\n');
}
return 0;
} void HeapSort(int Array[], int len){
int i;
int time = len;
for (i=0; i<len; ++i){
Swap(&Array[1], &Array[time]);
--time;
ShiftDown(Array, 1, time);
}
} void BuildMaxHeap(int Array[], int len){
int index = len/2; for (; index>0; --index){
ShiftDown(Array, index, len);
}
}
void ShiftDown(int Array[], int index, int len){
while ((2*index) <= len || (2*index+1) <= len){
if (2*index+1 <= len){
if (Array[index] < Array[2*index] ||
Array[index] < Array[2*index+1]){
if (Array[2*index] > Array[2*index+1]){
Swap(&Array[index], &Array[2*index]);
index = 2*index;
}
else{
Swap(&Array[index], &Array[2*index+1]);
index = 2*index + 1;
}
}
else
break;
}
else{
if (Array[index] < Array[2*index]){
Swap(&Array[index], &Array[2*index]);
index = 2*index;
}
else
break;
}
}
} void Swap(int *m, int *n){ //交换数据
int tmp;
tmp = *m;
*m = *n;
*n = tmp;
}

清橙OJ上相似的题目:http://blog.csdn.net/jdplus/article/details/19675351

九度OJ上相似的题目:http://blog.csdn.net/jdplus/article/details/19677345

参考资料:何海涛 -- 程序员面试题精选100题(05)-查找最小的k个元素[算法]

九度OJ 1371 最小的K个数 -- 堆排序的更多相关文章

  1. 【剑指Offer面试题】 九度OJ1371:最小的K个数

    题目链接地址: http://ac.jobdu.com/problem.php?pid=1371 题目1371:最小的K个数 时间限制:1 秒内存限制:32 兆特殊判题:否提交:5938解决:1265 ...

  2. 剑指Offer - 九度1371 - 最小的K个数

    剑指Offer - 九度1371 - 最小的K个数2013-11-23 15:45 题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是 ...

  3. 九度 1371 最小的K个数

    题目描述:输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 输入: 每个测试案例包括2行:第一行为2个整数n,k(1<= ...

  4. 九度OJ 1209 最小邮票数 -- 动态规划

    题目地址:http://ac.jobdu.com/problem.php?pid=1209 题目描述: 有若干张邮票,要求从中选取最少的邮票张数凑成一个给定的总值.     如,有1分,3分,3分,3 ...

  5. 九度OJ 1086 最小花费--动态规划

    题目地址:http://ac.jobdu.com/problem.php?pid=1086 题目描述: 在某条线路上有N个火车站,有三种距离的路程,L1,L2,L3,对应的价格为C1,C2,C3.其对 ...

  6. 九度OJ 1207:质因数的个数 (质数)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:5939 解决:1926 题目描述: 求正整数N(N>1)的质因数的个数. 相同的质因数需要重复计算.如120=2*2*2*3*5,共有 ...

  7. 九度OJ 1087:约数的个数 (数字特性)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:7349 解决:2306 题目描述: 输入n个整数,依次输出每个数的约数的个数 输入: 输入的第一行为N,即数组的个数(N<=1000) ...

  8. [程序员代码面试指南]数组和矩阵问题-找到无序数组中最小的k个数(堆排序)

    题目链接 https://www.nowcoder.com/practice/6a296eb82cf844ca8539b57c23e6e9bf?tpId=13&tqId=11182&t ...

  9. 【剑指Offer面试编程题】题目1371:最小的K个数--九度OJ

    题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 输入: 每个测试案例包括2行: 第一行为2个整数n,k(1< ...

随机推荐

  1. 展开/收缩 ul

    了一个展开收缩的东东,留着以后万一用到 后台递归生成的函数(这里是一个反射参数展示,支持多层级展开显示,后台反射如何多层级解析的方法有时间再补上吧) /// <summary> /// 递 ...

  2. 东芝超级本从win8到win7

    东芝超级本从win8到win7 2014年2月20日 11:08:46   1. 进入BIOS     调出关机选项,按住shift不松手,然后点选关机,彻底关机后,按住f2不松手,按下电源开机,就进 ...

  3. iOS开发中使用静态库 .a 文件

    ​​iOS开发中,在使用一些第三方库时,可能是一个静态库(比如GPUImage).这种情况下,需要编译出静态库文件(.a) ,然后配合响应的头文件(.h 文件)使用. 编译静态库,直接在Xcode中编 ...

  4. 兰亭集势笔试题:用最优方法从LinkedList列表中删除重复元素

    用运行速度最优的方法从LinkedList列表里删除重复的元素,例如A->B->BB->B->C,返回A->B->BB->C. 考试的时候没完全想明白,考完又 ...

  5. UDF 编写自定函数

    在Mysql的官方文档中有说明如何给Mysql添加新的函数. 添加的函数可分为3种: .自行编写函数的源码,将源码编译成动态库,然后使用Mysql的CREATE FUNCTION语句来将函数添加进My ...

  6. 初识jsp

    复习: 1.servlet生命周期: (1)默认是以第一次请求的时候创建并初始化Servlet,而且只做一次.(构造函数 init()) web.xml(配置后,是可以达到在服务启动后,立刻进行ser ...

  7. 布隆过滤器(Bloom Filter)

    一.布隆过滤器介绍 Bloom Filter是一种空间效率很高的随机数据结构,Bloom Filter可以看做是对bit-map的扩展,它的原理如下: 当一个元素被加入集合时,通过K个Hash函数将这 ...

  8. (转)使用OpenVPN的一些注意事项

    原文地址:http://www.365mini.com/page/16.htm 本文介绍的只是OpenVPN连接或使用过程中的一些注意事项,如果你尚未下载安装OpenVPN,你可以点击查看OpenVP ...

  9. 技术QQ群

    欢迎加入moss技术交流群. 欢迎加入微信技术交流群.

  10. DevExpres表格控件运行时动态设置表格列

    本文是系列文章,陆续发表于电脑编程技巧与维护杂志. DevExpres产品是全球享有极高声誉的一流控件套包产品!国内典型用户包括:用友.金蝶.神州数码.工信部.中国石化.汉王科技等众多大中型科技型企业 ...