首先先来看一道高盛面试的“真题”。
有25名短跑选手比赛竞争金银铜牌,赛场上有五条赛道,因此一次可以有5个人同时比赛。比赛并不计时,只看相应的名次。
假如选手的发挥是稳定的,也就是说如果A比B跑得快,B比C跑得快,那么A就一定比C跑得快。那最少需要多少组比赛才能决出前三名呢?
其实要算出第一名并不难,这道题难就难在,还要算出二三名。
我第一次做这道题的时候,完全想不出一个像样的方法来,只会一步一步慢慢算:
既然要决出前三名,那么我就每次比赛都淘汰2名选手,保留前3名,然后再新加入2名选手再次比赛,一直比到所有选手都参加完比赛。
用这个笨方法算出最快的前三名,一共需要进行11局比赛,不仅如此,最快那名选手最多还可能要跑十一次!
(如下表)
比赛回合数 | 剩余人数 |
0 | 25 |
1 | 23 |
2 | 21 |
3 | 19 |
4 | 17 |
5 | 15 |
6 | 13 |
7 | 11 |
8 | 9 |
9 | 7 |
10 | 5 |
11 | 3 |
那最优解是要跑多少组比赛呢?
答案是只需要7局比赛。
如下表,我们将所有选手分为ABCDE五个组,假设A1是这个组的第一名,A5是这个组的最后一名,A2,3,4以此类推。
前5局比赛是分别选出每一组的第一名;
A组 | B组 | C组 | D组 | E组 |
A1 | B1 | C1 | D1 | E1 |
A2 | B2 | C2 | D2 | E2 |
A3 | B3 | C3 | D3 | E3 |
A4 | B4 | C4 | D4 | E4 |
A5 | B5 | C5 | D5 | E5 |
第6局比赛是让每一组的第一名再比赛一次,选出冠军,假设按照 顺字母序A1最快,E1最慢;
第7局比赛则让B1、A2、C1、A3、B2组成一组再次比赛,前两名就是亚军和季军。
A组 | B组 | C组 | D组 | E组 |
A1 | B1 | C1 | D1 | E1 |
A2 | B2 | C2 | D2 | E2 |
A3 | B3 | C3 | D3 | E3 |
A4 | B4 | C4 | D4 | E4 |
A5 | B5 | C5 | D5 | E5 |
解释:由于只需排出前三名,所以D1和E1在第六场比赛后就可以排除在外了;
至于亚军的候选人有两位,他们都是直接输给第一名的人,第一位是附加赛中的B1,另外一位就是第一组的A2,仅此而已;
季军的候选人则有四位:一位是附加赛中排第三的C1、一位是第一组排第三的A3,一位是第二组的第二名B2,最后一位是亚军的落选人(如上表);
而他们五个人正好能组成一局比赛,也就是第7局比赛,而比赛成绩的前两名就是亚军和季军。
我的笨方法与最优解最大的差别就在于“我做了很多无用功”!
在最优解上,冠军只跑了2次比赛,而且不做任何多余的运算,例如第七局比赛直接排除D1和E1。
而我的方法虽然能算出很多选手之间的相对排名,但是题目要求的只是求出前3名,其他人的排名就算算出来也没有任何用途——无用功。
这道题给我的启发很大,我从小到达都爱使用笨方法来解决事情,在感到时间不够用时,想到的只有“早上再早一点起床”/“晚上再晚一点睡觉”,却从来没想过停下来,思考一下自己做事的方法 有没有可以改进的地方。
正如吴军老师所说:“今天很多人收入不高,想到的只是简单地加班,延长工作时间,做更多的事情,但是却没有从更高的层次想问题——捡再多的芝麻也难以抵得上一个西瓜。”
参考资料:
吴军. 什么是计算机的数据结构?[J/OL]. 得到APP.
吴军. 从二叉树数据结构到具体问题共性的抽象化[J/OL]. 得到APP.
吴军. 计算机经典算法:锦标赛排序算法[J/OL]. 得到APP.
大家好,我是沈哲汉,英文名是Hanson,日文名是ハン。
在大学时我学习了建筑设计;毕业后因为热爱动漫,自学了日语,并考过了N1;在有幸结识了“得到”APP之后,开始了写作;现在是007・不写就出局 13班成员。
平时会公众号上分享一些读书感悟、日语知识以及一些生活的小窍门等,期待你的关注~微信公众号:哲汉的学习记录(ID:HahnPro)