百度笔试题7.2

题目二:

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中就这个问题写些伪代码。  

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

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cyf31

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值