在浩瀚无垠的东方玄域有无数的大大小小的门派,分布在丛山峻岭之间。其中位列顶尖有A门派,T门派,B门派,H门派,M门派,Z门派这6大势力最强,受众最广。每年都会通过笔试面试,挑选码农入门派内修炼。而码农在修炼的过程中有三大神器必看:
写代码无论是遇到任何问题上,只要上Stackoveflow都能查到答案;
查看源码,无论是复杂的框架还是小的脚本,都可以在GitHub上搜索查到;
学会精妙的算法尤其是面试大门派之前,必刷LeetCode ;
小编周末在家,也开始静心的修炼起来,今天来刷一道在LeetCode上非常有名的题目CoinChange,据说这道面试题有师兄在阿里被面过,来一起挑战一下。
给你不同面额的硬币coins
和一个总金额amount
。需要你来写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1
。
示例:
输入: coins = [1, 2, 5], amount = 11
输出: 3
解释: 11 = 5 + 5 + 1
示例:
输入: coins = [2], amount = 3
输出: -1
如果不太动脑子不考虑效率的话,抱着不管三七二十一先做出来再说的话,肯定是暴力遍历比较容易想到。其实就是一个很简单的数学公式11=x1* 1+x2*2+x3*5,我们直接三层循环即可。
面值为1的钱币最大11张,x1的搜索空间为0-11
面值为2的钱币最大5张,x2的搜索空间为0-5
面值为5的钱币最大2张,x3的搜索空间为0-2
1).第一步算出每一张币种的最大张数
如果我们的输入的coins=[1,2,5],target =11 ,那么每一种币种的最大张数为11,5,2
2).进行空间搜索,凑到面值为11的组合
通过暴力的循环迭代,把凑到的钱币为11的组合用yield记录下来。
得到的组合示例为:
(4, [0, 3, 1])
4是使用钱币的张数,0表示0张1元面,3表示3张2元面,1表示1张5元面值
(3, [1, 0, 2])
3是使用钱币的张数,1表示1张1元面,0表示0张2元面,2表示1张5元面值
3).对组合的结果进行排序
4).运行看一下结果
最后的结果就是{1: 1, 2: 0, 5: 2} ,最少用3张:1元面值*1,5元面值*2
上面的解法平铺直叙,但是很明显有致命的缺陷,因为c1,c2,c3都是写死的,这样的话肯定不行,如果我们的币种的数目变化的不是3种,那上面的代码就直接挂了。
因为我们代码里写死了循环3层,其实每一个币种的面值也不一定是1,2,5,所以我们需要换一个思路来处理,代码优化如下:
三个币种【1,2,5】,每一种币种若要凑11元的最多使用张数为【11,5,2】,那么对于每一个面值的来说组合为:
1元:[(0,1),(1,1),(2,1),(3,1)...(11,1)] 即为0张1元,1张1元,2张1元,3张1元
2元: [(0,2),(1,2),(2,2),(3,2)...(5,2)]即为0张2元,1张2元,2张2元,3张2元
5元:[(0,5),(1,5),(2,5)]即为0张5元,1张5元,2张5元
然后我们把所有的币种的组合进行全排列即可
我们先得出币种和最大的张数的一个mapping,就是[(11, 1), (5, 2), (2, 5)]
接着进行把币种的单一面值的组合都列出来,就是:
[[0, 1], [1, 1], ... [11, 1], [0, 2], [1, 2],... [5, 2], [0, 5], [1, 5], [2, 5]]
最后用itertools里面的permutations进行全排列,剩下的其实就是对全排列的组合进行排序,就很简单了。
上面的解法时间复杂度很高,而且效率很低,完全没有美感可言,非常简单粗暴。在真正的生成环境是不能这样使用的,很明显我们需要另辟蹊径。这个问题是一个很明显的动态规划问题。
动态规划算是算法里面比较难理解的一个概念,每个动态规划都是从网格开始。
对于面值1元,2元,5元,要凑11元,我们从0开始最大使用11张。
每一个等级的钱数我们通过网格画出使用最少的钱数,那么这个问题就分解为1+10: 寻找满足1元使用最少的钱数 和10元使用最少的钱数
2+9: 寻找满足2元使用的最少的钱数,寻找满足9使用最少的钱数
3+8: 寻找满足3元使用的最少的钱数,寻找满足8元使用最少的钱数
以此类推。。。
设计一个dp容器,进行存储每一个面值需要的最少的张数,一开始设置为正无穷大;
用2层循环去搜索这个网格,把每一个面值的使用的最少张数存进网格
我们输入几个测试用例看一下结果:
测试用例全部通过,懂点算法还是很有用点,尤其是面试招聘,行走江湖还是需要几把刷子呢!有的同学说面试的时候严格的像造火箭,招进去干活的活就是每天拧螺丝。
确实现实很骨干,但是拧螺丝也得有本书先混进大厂才行啊。好了,不啰嗦啦,小伙伴赶紧Python学起来!
end
有热门推荐????
1. 超全Python IDE武器库大总结,优缺点一目了然!
2. Python 30道高频面试题及详细解答
3. 精华技巧,学会这几招可以假装是Python高手
4. 哇!用Python读取CVS文件竟然有5招,据说90%的人只会2招
菜鸟编程大本营,现已正式上线!
接下来我们将会在该公众号上,为大家分享优质编程语言里趣味的干货,通俗易懂的实战案例,经验分享,让菜鸟也爱上编程。
点这里,领取新手福利