如何在一亿个数当中找到最大的10000个数?腾讯云开发者社区

在日常生活中,我们经常会遇到排序问题:

在打扑克牌的时候,原本拿到手上的牌是乱序的,我们会按照自己喜好的顺序一张一张排好手上的牌,最后看起来是顺眼的。

摄影师给毕业的同学们拍照片,要求同学们站好队形,然后要求中间高,两边低的方式排队。如果摄影师发现某个同学的高度跟旁边的同学不协调,这个同学必须马上调整自己的位置,最后是一派整齐的景象:

经常泡图书馆的泡友,会发现有很多志愿者会帮忙整理图书位置。每一本书的书背上面都有一张标签,书架上的图书需要按照标签上的编号排好顺序,这样泡友才能快速找到想要的图书。

这些例子就是排序问题了。排序问题不仅在生活中常见,在IT届也常见。据说,某科技公司在做一个项目时遭遇大量排序问题,运算速度奇慢,项目经理非常头痛,为招收能制伏排序问题的人才,干脆总结成了一道题目:

如何在一亿个数当中找到最大的10000个数?

方法一:重复寻找法

我们可以先用最直观的方式来做这道题目,起个名字叫重复寻找法:

第1步:我们先在这一亿个数当中,寻找到最大的那个数字,把它记录下来。

第2步:从这一亿个数字中,剔除这个最大的数字。

第3步:重复执行第1步和第2步,直至记录下来10000个数字。记录下来的结果即为所求。

以挑苹果为例,重复寻找法就好比我们在苹果堆中挑苹果的时候,先在所有苹果里面挑出最好的一个,然后继续在剩余苹果里面再挑出最好的一个……如此类推。

怎么找到最好的苹果?那必须拿着某个苹果,对比一遍所有苹果,如果发现有更好的苹果,把好的苹果拿在手上,把次好的苹果放下,直至对比完所有的苹果后,手上拿着的就是最好的苹果。

重复寻找法,就好比在苹果堆中不断挑最大最好看的苹果到自己的篮子里

为了方便讨论起见,我们设n=1亿

我们知道,求n个数最大值的比较次数为n,求最大值的过程需要执行10000次,因此,重复寻找法的总比较次数为:

10000×n

虽然这个问题有答案了,但是心里貌似有一些遗憾,不知道大家感受到了没?

其实,遍历10000次,这个次数有点多,为什么不可以遍历1次就得到结果呢?

方法二:局部淘汰法

实际上是可以的,还有一个能够一步到位的方法,叫做局部淘汰法:

第1步:先创建一个数组,保存这1亿个数字中的前10000个数字,计算数组的最小数字。

第2步:遍历剩下的数字。如果遍历到某个数A大于数组的最小数字,那么则用A替换掉数组的最小数字。并重新计算数组的最小数字。

第3步:遍历完成后,数组内的数字即为所求。

以打麻将为例,一开始我们拿了n个牌,局部淘汰法类似我们在打麻将过程中,如果摸到一个比自己手上最坏的牌要好的牌,就打出自己手上最坏的牌……如此类推,使得胜利的概率不断增大。

局部淘汰法,可以类比打麻将的过程,不断更换手上的牌,使得胜利的概率越来越大

这样,遍历1次就能得到最后的结果了。总比较次数如何呢?

最好的情况是,如果这1亿个数字刚好已经是降序排列,那么前10000个数字就是结果,只需要进行1次最小值的计算(比较次数为1×10000),9999万次最小值的比较(次数向上近似为n)。

最坏的情况是,如果这1亿个数字刚好已经是升序排列,那么直到最后的10000个数字才是最终结果,因此需要进行9999万次最小值的计算(比较次数为n×10000),9999万次最小值的比较(次数向上近似为n)

因此,平均的情况是,要算5000万次最小值(比较次数为1/2×n×10000),要算9999万次最小值比较(次数向上近似为n,因此总比较次数近似为:

1/2×n×10000=5000×n

总比较次数下降了一半,这个优化有点用。

但是……大家有没有觉得这个方法还有优化空间?

方法三:最小堆维护法

这个问题嘛……事实上是有的。这个方法能够大幅度降低总比较次数,称之为最小堆维护法:

第1步:先利用前10000个数字,搭建一个元素个数为1万的最小堆。

有同学可能会问,什么叫做最小堆呢?在这里解释一下:

首先,什么是堆

在计算机领域中,堆这个概念与生活中的有一点点类似,一般的堆也是上面窄下面宽的结构。堆结构,非常类似圆木堆放的结构,充满大自然的气息。

堆结构,可能源自圆木木堆的灵感

堆(heap)是一种基于树(tree)的特殊的数据结构。堆有两种形式,分别是最大堆(maxheap)和最小堆(minheap)。在堆顶的节点则被称为根节点。

我们关心最小堆就可以了。最小堆中,如果节点A是节点B的父节点,节点A中的键值必定小于或者等于节点B中的键值。根节点是堆的最小值。

堆的形式有非常多,不过堆的最常见实现形式是二叉堆(binaryheap),最小二叉堆一般也是被直接简称为最小堆,因此我们只需要理解二叉堆即可。我们可以画一个最小二叉堆的例子出来感受一下:

一个最小堆示例

对图中的最小堆分析,一共有三层圆圈,称之为节点,每一个上层的节点都连着下层的两个节点,而且上层节点的键值均比下层的两个节点的键值要小。这个就是最小堆的特征。

我们来继续做题吧:

第2步:遍历剩下的数字,与最小堆的根元素键值进行对比。如果遍历到某个数确实大于根元素的键值,则替换根元素的键值,并进行堆调整。

第3步:遍历完成后,最小堆当中的所有元素对应的数值即为所求。

n×log210000

总比较次数进一步下降了5000÷14>350倍,这个优化确实漂亮。

比赛流程

比赛名称:

有方AI萌新挑战赛

EmbarkAIMengXinChallenge

比赛赛题:

5道编程题

参赛对象:

所有正在【萌新学习群】学习【AI初探:数据科学】课程的学生都有资格参与

参赛形式:

比赛规则:

是不是很简单!只要你参与,动动你聪明的小脑袋,就能够把你的智慧转换成压岁钱~

而且还是真!金!白!银!想一想,喜欢的都能买买买了呢!

THE END
1.排列三中奖中二个号,别再错过希望!1、和数值法:将“排列3”的3位数相加,研究它的三位数和数值的规律,它的和数值范围在0-27之间,容易掌握中奖走势,所以是比较常用的一种办法。 2、奇偶法:研究3个数中奇偶数出现次数的方法。 3、大小法:把0-4定为小,5-9定为大,研究3个数大小搭配的方法。 https://res.17500.cn/arts/sdetail-10415504.html
2.排列组合概率:从0,1,2,.,9十个数字中任选3个不同的数字,求三个∴P(同时含0和5)=8/C(10,3)=1/15.∴P(不含0或5)=14/15. 解析看不懂?免费查看同类题视频解析查看解答 更多答案(4) 相似问题 从1,3,5,7,9这5个数字中任取两个数字,从0,2,4,6这四个数字中任取两个数字 求数学好的同学,排列组合问题:0-9这十个数字,到底有多少种不同的排列组合(允许重复https://www.zybang.com/question/4366dec65278c13041e6e6403a6ec002.html
3.GitHub举个例子来说吧,比如 nums1 = {3},nums2 = {2, 4, 5, 6, 7},K=4,要找两个数组混合中第 4 个数字,则分别在 nums1 和 nums2 中找第 2 个数字,而 nums1 中只有一个数字,不存在第二个数字,则 nums2 中的前 2 个数字可以直接跳过,为啥呢,因为要求的是整个混合数组的第 4 个数字,不管 numhttps://github.com/sunmiaozju/leetcode
4.sql计算两个小数乘积学会这个方法,掌握乘法中乘积最大最小的解法用2,5,6,8,9这五个数字组成一个三位数和一个两位数,乘积最大是95×862=81890。 这时有同学可能又会提出,这5个各不相同的数字中如果含有0,要怎样排乘积才能最大呢? 按照上述方法,仍然将各不相同的5个数按照从大到小的顺序排列起来,然后并分成3级,最后一级只有一个0,而0和“0”一样大,故这个0可以放在https://blog.csdn.net/weixin_39574869/article/details/111385446
5.Java面试题大全(整理版)1000+面试题附答案详解最全面看完稳了7、一个字符串类型的值能存储最大容量是多少? 8、Redis 的持久化机制是什么?各自的优缺点? 9、Redis 常见性能问题和解决方案: MySQL 面试题 1、MySQL 中有哪几种锁? 2、MySQL 中有哪些不同的表格? 3、简述在 MySQL 数据库中 MyISAM 和 InnoDB 的区别 https://maimai.cn/article/detail?fid=1752437513&efid=uSgZIWSJqvkGwxf4vJW75w
6.排列五走势图排列五中三数字区间综合振幅走势图2体彩排列五中三数字区间综合振幅走势图2 期数设置 - 期 形态 组3 组6 最近50期 最近100期 数字区间: 区 0: 1: 2: 3: 4: 标记形式选择: 不带遗漏数据 遗漏分层 辅助线 带折线 序号 期号 奖号 百十位和尾振幅 百个位和尾振幅 十个位和尾振幅 百十位差值振幅 百个位差值振幅 十个位差值振幅 https://zst.cjcp.com.cn/cjwssc_rs/view/ssc_szqjzh-lhwzf-2-pl35.html
7.3D只要你选择的1个胆码中开奖号码其中之一,则用胆码全拖以上45个组合,一定中组选6(但不含豹子,如111,222);还可以通过排除奇偶,大小等减少投注组合;如判断出组3则不用全拖,只要包下含胆码的组合买组3。 例如:220期:开158,如用5做胆,排除组3,余36注组选6。 https://www.360doc.cn/mip/63024184.html
8.浙江体彩网>>玩法规则>>中国体育彩票“排列3”游戏介绍“排列3”为全国联网的体育彩票玩法,于2004年12月9日在浙江上市,迅速成为深受彩民喜爱的彩种。从2005年底开始,“排列3”进行了一系列派送活动,更激发出彩民的投注热情,同时返奖率也屡次创造纪录。 玩法规则 “排列3”是从000-999的数字中任选一个三位数为投注号码进行投注,投注方式分为直选投注和组选投注。直选投https://www.zjlottery.com/Rule/Lotto/201005/10770.html
9.重发不容错过的彩蛋:官方排除法&花名口令(余兴派对第二季剧本中看似怪异的台词、情节,在后续其他人的故事中都能够获得解答,挖坑、填坑做得是有条不紊。不过就像是拼图一般,只盯着一块看时不明所以,而只有当所有拼图都归位,才会佩服编剧们的设计巧妙(等本季完结后,再来整理补充一波剧情上容易错过的前后呼应)虽然本剧的思路确实适合以剧集展开,一集一个嫌疑人、一种画风,https://movie.douban.com/review/15421184/
10.2015年国家公务员备考:公务员行测必考必会——数字推理1、 数列中每一个数字都是n 的平方构成或者是n 的平方加减一个常数构成,或者是n的平方加减n构成。 2、 每一个数字都是n的立方构成或者是n的立方加减一个常数构成,或者是n的立方加减n。 3、 数列中每一个数字都是n的倍数加减一个常数。 以上是数字推理的一些基本规律,必须掌握。但掌握这些规律后,怎样运用这https://xiangyang.huatu.com/2014/0822/902666.html
11.关于中国体育彩票排列3游戏组选2码全包购买方式的公告[江苏体彩网]中国体育彩票排列3游戏组选2码全包购买方式是指从“0-9”中选择2个或2个以上的不重复数字,所选数字分别与“0-9”每个数字组成的3位数字的所有组合进行的多注组选投注。组选2码全包票面标明“组选2码全包票”字样,并显示所选的2个不重复数字。 特此公告。 https://www.js-lottery.com/wfzq/p3p5/wfzq/cms/post-133855.html
12.7星彩奖池破3亿助力二等奖奖金惊喜“升级”将选择号码的所有排列组合均进行投注 组成多注单式投注的投注方式 而前区全组合投注是组合投注的一种 是将前区选择的6位数字的 所有排列组合均进行投注的投注方式 如前区投注123456,后区投注1 则购买了前区由 1、2、3、4、5、6这6个数字 后区由1构成的所有7星彩投注号码 http://tyj.lishui.gov.cn/art/2021/12/24/art_1229216253_58921816.html
13.循环游离DNA中肿瘤相关突变基因检测的参考品的制作方法2.目前,获取肿瘤基因相关信息的主要来源仍是受试者的肿瘤组织样本。然而,对于部分晚期癌症患者而言,无法得到肿瘤组织样本,也不适合进行动态监测。 3.大量的临床研究证明,在外周血中存在循环的游离dna(circulating free dna,或cfdna),而在肿瘤患者的外周血cfdna中包含循环肿瘤dna(ctdna,circulating tumor dna)。对血浆https://www.xjishu.com/zhuanli/27/202210293003.html