《programming for the puzzled》第六章
涉及到的知识:案例分析,分治法。
在9个硬币中找到一个赝品。假的比真的重一些,你的任务是使称重的次数最少。你需要称几次?
穷举,选出一个硬币与其它八个依次对比,最差需要称八次。
用分治法可以做得更好。先从9个硬币中选出四个,分两组称。有三种情况:相等,则赝品在剩下的五个硬币中。前一组较重,或后一种较重,赝品在这两个硬币中的一个,再比较一次即可确定赝品。在后两种情况中,称两次即可确定。第一种情况,从五个硬币中选出4个,再比较,又有三种情况。相等的情况,赝品是多余那个,一共比较了两次。如果不想等,又比较一次,共比较了三次。这是不是最优的结果呢?可以把九个硬币分三份,称重结果一样的。
用递归来实现分治法。
1 | # coding:utf-8 |
通过分治法不断减小问题规模可以最小化比较次数。我们也可以顺着整个硬币序列依次比较,但在最坏的情况下我们需要比较整个序列。
练习1.如果给一个所有硬币都相同(即没有假币)的列表,程序会返回第一个硬币是假币,解决这个bug。
用找来的”假币”重量与输入的列表的第一个值和最后一个值对比就行了。如果都一样,那就是没有假币。
1 | # 现在进行分治了 |
本章代码
https://github.com/zwdnet/MyQuant/blob/master/44/06/fz.py
我发文章的三个地方,欢迎大家在朋友圈等地方分享,欢迎点“在看”。
我的个人博客地址:https://zwdnet.github.io
我的知乎文章地址: https://www.zhihu.com/people/zhao-you-min/posts
我的微信个人订阅号:赵瑜敏的口腔医学学习园地