从1亿个数中找出最大的1000个数

xlhnuaa 2011-08-28 04:47:07
现在有一个1亿个数的整型数组,要从中找出最大的1000个数。并且要求效率尽可能地高,占用的额外空间尽可能的少,不能使用任何库函数。
...全文
1931 30 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
lumingming 2011-12-14
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 luciferisnotsatan 的回复:]

引用 7 楼 wwwzys 的回复:

引用 6 楼 mervynhit 的回复:

我们只要定义一个的链表,将1亿个数用插入排序法插入,当链表的里元素的个数大于1000时,每插一个数就丢掉一个最小值(head节点),不就行了吗。

不错的方法时间复杂度O(n) 空间复杂度O(n)

这个方法时间复杂度啥时候成O(n)了??
[/Quote]你认识是多少呢
wangxiaotao1980 2011-08-30
  • 打赏
  • 举报
回复
类似此种问题,是快速排序的变种算法。
fcly1981826ly 2011-08-30
  • 打赏
  • 举报
回复
啊。。学习
xlhnuaa 2011-08-30
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 ken_scott 的回复:]

引用 8 楼 sohu_2011 的回复:
建议看看<编程之美>其中有详细讨论;

里面有两种方法:
1.前1000个建立一个最小堆,比较之后的数,如果大于堆的头上的数(1000中最小的),将这个数替换成新比较的数,并调整结构使之仍然是一个最小堆,这样,遍历完后,堆中的1000个数就是所需的最大的1000个
2.用(部分)快速排序(从大到小排),因为快整排序是分块有序的,每次排会有(a……
[/Quote]

谢谢哈,学习了
ken_scott 2011-08-30
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 sohu_2011 的回复:]
建议看看<编程之美>其中有详细讨论;
[/Quote]
里面有两种方法:
1.前1000个建立一个最小堆,比较之后的数,如果大于堆的头上的数(1000中最小的),将这个数替换成新比较的数,并调整结构使之仍然是一个最小堆,这样,遍历完后,堆中的1000个数就是所需的最大的1000个
2.用(部分)快速排序(从大到小排),因为快整排序是分块有序的,每次排会有(a,...,b,c,d,...,e)其中a..b是无序的,但都大于等于c的,d..e是无序的,但都小于等于c的, 如果a..b的个数等于1000,则a..b就是所要的,如果a..b的个数大于1000, 此时只要继续a..b做快速排序(相同动作),找出前1000个,如果a..b及c的个数不足1000,则再取两个d..e最大的前n个数就可以了(递归 相同处理)
a7765033 2011-08-30
  • 打赏
  • 举报
回复
大样本实验,且属于均匀分布。

如,1万个数字属于[1,100],那么有1万/100 = 100个最大数字100。

所以假设整形数字属于[0,42 9496 7295(2^32-1)],即无符号32位,那么有
42 9496 7295 / 100 0000 ≈ 4294
个以 1百万 为基数的大数字,且4294 > 1000

所以遍历1亿数字,大于 1百万 的放入集合A
此时集合A的数字均大于 1百万,而且只有4294个,用什么排序都很快了,比如快速排序

----------------------------------------------------------------------------------
基数排序的话这道题应该还行吧?
用比较法的话会受到数字个数的限制啊。。。
turing-complete 2011-08-30
  • 打赏
  • 举报
回复
小顶堆 时间复杂度 N*logK
qq120848369 2011-08-30
  • 打赏
  • 举报
回复
随便写个堆.
k20220630 2011-08-29
  • 打赏
  • 举报
回复
个人认为桶排序(我们这里是这样说的,原理大概是位数越多越大,位数相同时第一个数越大这个数越大)可以
只要不是变态数据(比如9*(10^100)和1相比)、、
xuukai 2011-08-29
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 k_mlgb 的回复:]

个人认为桶排序(我们这里是这样说的,原理大概是位数越多越大,位数相同时第一个数越大这个数越大)可以
只要不是变态数据(比如9*(10^100)和1相比)、、
[/Quote]

这个想法也很好。
xuukai 2011-08-29
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 mervynhit 的回复:]

我们只要定义一个的链表,将1亿个数用插入排序法插入,当链表的里元素的个数大于1000时,每插一个数就丢掉一个最小值(head节点),不就行了吗。
[/Quote]

well done!
koalapheonix 2011-08-29
  • 打赏
  • 举报
回复
看看堆就大致明白了。
xlhnuaa 2011-08-29
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 sohu_2011 的回复:]

建议看看<编程之美>其中有详细讨论;
[/Quote]

可以问具体在第几章吗?
xlhnuaa 2011-08-29
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 hongwenjun 的回复:]

昨天 回来这个贴子,恢复的时候断线了.

一亿分成 100 x 100W
然后 100次 100W中找1000个最大数
可以找到10W个最大数
然后10W个中找 1000

懂的人 分析下 算法效率
[/Quote]

分割的思想
hongwenjun 2011-08-29
  • 打赏
  • 举报
回复
昨天 回来这个贴子,恢复的时候断线了.

一亿分成 100 x 100W
然后 100次 100W中找1000个最大数
可以找到10W个最大数
然后10W个中找 1000

懂的人 分析下 算法效率
weixiaoshashou 2011-08-29
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 dyangrun 的回复:]
弄一个队列,长度为1000
然后遍历你的1000个数
链表不满的时候做从大到小的排序添加数
队列满了之后,每次都对比队尾如果不大于队尾就下一个
大于的话用2分查找法确定位置,然后移除队尾~
遍历完你就得到了1000个最大的数了,
不过你题目不是很清楚,例如1000个数需不要重复的之类,不过这种方法基本上上是可以解决问题~
只是效率一般,额外空间也就1001个数
[/Quote]
可以用 STL 里的 Set 改变一下他的默认排序准则,设置为逆序排序准则,这样子替换最后一个就可以
sadly_coder 2011-08-29
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 luciferisnotsatan 的回复:]

引用 7 楼 wwwzys 的回复:

引用 6 楼 mervynhit 的回复:

我们只要定义一个的链表,将1亿个数用插入排序法插入,当链表的里元素的个数大于1000时,每插一个数就丢掉一个最小值(head节点),不就行了吗。

不错的方法时间复杂度O(n) 空间复杂度O(n)

这个方法时间复杂度啥时候成O(n)了??
[/Quote]


对一千个元素的链表执行插入操作 时间复杂度为O(1),遍历n个元素的时间复杂度为O(n),结果O(1)×O(n)为O(n). 是这样么?
mengmingtao 2011-08-29
  • 打赏
  • 举报
回复
哦,选择第1000个数的复杂度也是n。整体复杂度是O(n)。只需要O(1)的额外存储空间即可。
mengmingtao 2011-08-29
  • 打赏
  • 举报
回复
首先使用选择算法选出第1000大的元素。复杂度为O(lg n)。
对1亿来说还是很小的。然后以该元素为分割进行partition。把比该元素大的放到前面,其余不理。复杂度为O(n).
xlhnuaa 2011-08-29
  • 打赏
  • 举报
回复
主要是这个1亿,数据量太大了,用平常的排序方法,效率和空间的利用率,肯定不符合要求。。。不知道有没有相应的例程
加载更多回复(10)

65,184

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧