Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4067229
  • 博文数量: 251
  • 博客积分: 11197
  • 博客等级: 上将
  • 技术积分: 6862
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-05 14:41
个人简介

@HUST张友东 work@taobao zyd_com@126.com

文章分类

全部博文(251)

文章存档

2014年(10)

2013年(20)

2012年(22)

2011年(74)

2010年(98)

2009年(27)

分类: C/C++

2011-03-25 13:14:05

昨天参加阿里巴巴的笔试,有一道题目要求从N个面试的人中挑选出M个成绩最好的人(M<=N, 并假定M个人的成绩都不一样),求挑选程序的最优时间复杂度()。

选项包括:O(NlogN), O(N*min(M, logN)), O(N*logM), O(N)

 

O(NlogN)的算法是完全有可能的,使用堆排序,快速排序等将N个元素排序,选取前M个元素即可。

 

O(N*logM)的算法也是有可能的,将前面M个元素构建为最小堆,将后面N-M个元素一次与堆顶比较,如果比堆顶元素大,则与堆顶交换,并将前面M个元素调整为最小堆。

 

在考试时,我觉得不存在O(N)的算法,另外我认为使用最大堆,效率可能更优,即构建最大堆M次,依次挑选M个最大的元素,时间复杂度为O(M*logN)昨天晚上回去跟同学讨论,他选的O(N),但也不知道算法如何实现,只是记得寻找从数组中寻找第K大的元素存在O(N)的算法。

 

早上google了一下寻找第K大元素的方法,主要有(假设数组有N个元素):

1.  使用选择或冒泡算法,排出前K个元素,时间复杂度为O(M*N)

2.  使用排序算法,将N个元素排序,取第K个,时间复杂度为O(N*logN)。

3.  使用快速排序,从数组中随机找出一个元素X,把数组分成比X小和比X大的两部分,假设比X小的部分元素个数为B,则:

(1)   如果B >= K,则递归从比X小的部分找第K大的元素。

(2)   如果B < K,则递归从比X大的部分找第(K-B)大的元素。

 该算法的时间复杂度接近O(N)(求证明),而且这种方法也能解决上面的笔试题。

4.  使用最小堆,类似笔试题中O(NlogM)的算法。

5.  使用最大堆,类似于笔试题中O(MlogN)的算法。

6.  使用hash表,从大到小统计K个元素即可,时间复杂度为0(N),但提高了空间复杂度。

 

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

cangt2011-04-13 19:41:18

用1位来表示每个数

flyd10052011-04-13 10:14:54

如果读过下面的书,就会发现是这本书中第一个例子的变形,很简单

数据结构与算法分析:C语言描述(原书第2版)
http://book.douban.com/subject/1139426/

浙江大学就用这本书讲的数据结构与算法分析课