百度笔试题7.2

来源:互联网 发布:菏泽矩阵直销软件 编辑:程序博客网 时间:2024/06/06 17:19

题目二:

http://topic.csdn.net/t/20061101/15/5125398.html

 

内存中有一个长数组,条目数为10万,数组单元为结构体struct arraysizeof(struct   array)512字节。结构有一int型成员变量weight。现需要取得按weight值从大到小排序的前500个数组单元,请实现算法,要求效率尽可能高。  

关键是   效率尽可能高

 

Answer1

http://topic.csdn.net/t/20061101/15/5125398.html

当年我面试百度的时候,也让我现场说出这道题的思路,最后我也是说快排的方法,  

可是那位老程序员笑了笑,就把我bs了,回到家,收到了拒信。  

反复思考了一个周末,终于明白了还有一种更好的排序方法,在解决此问题时可以达到O(n)  

  那就是堆排序,建堆时间为O(n),然后换动500次堆顶,时间为O(500×log(n)),所以总的复杂度还是O(n)  

(数据总量大小为51M,机器默认的栈大小为2M,数组有可能就存不下)

 

Answer2:

如果不限内存的栈大小,那么采用堆排序。如果限制内存的栈大小,考虑到内存的栈不过存放10万个数据。开辟一个数值a[500]

参考:

http://blog.csdn.net/lanphaday/archive/2008/12/18/3547776.aspx

 

Answer3

其中一种策略就用正态函数来建立模型,以达到高效的要求。  

  1.遍历一次所有记录,就可以得到最大值a,最小值b和平均值v(把所有值相加,再除以记录数)  

  2.再次遍历一次所有记录,用各个值n   减去   平均值v,再求各个差值d   的平方和p,这个值能代表数值的分布变化程度。  

  3.a,b,v,p这四个数据,以及正态分布函数,模拟得到数据的分布情况,代入概率参数500/100000=0.05,得到一个前最大500位的最小可能数值g(学过正态分布的,都应该知道可以查表和简单的乘法得到这个值,所以不需要什么复杂运算),同时可以把0.05改为0.05111(或是采用更好的模型)之类的,总之要保证前500位都会大于g  

  4.再次遍历一次所有记录,取出所有大于g的数,模拟函数好的话,会取得5百多一点点的数据量,再在这5百多的数据量中,排出前500最大的数据,结束。  

  总复杂度大概是   3*n   +   500*log500),有时间的话,我可能会在我的BLOG中就这个问题写些伪代码。  

  不过肯定有更高效的策略。

 

原创粉丝点击