Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2788477
  • 博文数量: 471
  • 博客积分: 7081
  • 博客等级: 少将
  • 技术积分: 5369
  • 用 户 组: 普通用户
  • 注册时间: 2012-01-04 21:55
文章分类

全部博文(471)

文章存档

2014年(90)

2013年(69)

2012年(312)

分类: C/C++

2012-09-24 10:50:37

从一个师弟那里得到一个百度的笔试题:

有10000个数,分成20组(m),每组500个(n),按倒序排列,请设计一个算法,找出这10000个数最大的500个。

如果把题目简化一下,是两组,那么这个题就简单了,考察的就是一个归并排序了,那复杂度就是O(n)了。其实对于20组可以利用同样的思路。

把这20组树表示为:
X1,1 X1,2 … X1,n
X2,1 X2,2 … X2,n

Xm,1 Xm,2 … Xm,n

首先将X1,1 X2,1 … Xm,1排序,复杂度为O(mlgm),这样就可以找到这批数据中的最大值,比如为Xk,1,那么最大的那个数位Xk,1,然后我们可以把Xk,1删除,然后把Xk,2插入到适当的位置,这样又可以删除最大的数,重复此过程,直到找到最大的n个数。把一个数插入到合适的位置的时间复杂度为O(m),那么总的时间复杂度为O(mlgm) + O(mn)。

后来想想可以利用堆来加速,开始将X1,1 X2,1 … Xm,1调整成大顶堆,时间复杂度为O(m),删除堆顶,比如为Xk,1,那替换为Xk,2,调整为大顶堆,时间复杂度为O(lgm),重复此过程,直到找到最大的n个数。总共的时间复杂度为O(m) + O(nlgm)。

阅读(1185) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~