一道Python面试题,硬是没憋出来,最后憋出一身汗!

Python语言目前是最火的语言之一,语法简单,功能强大,最新的TIOBE已公布2020年6月的编程语言排行榜,Python已经连续多个月都在前三甲了,非常火爆!

现在学习Python的同学越来越多,面试的环节,很多面试官让你任选语言进行编程。Python因为简单,很多小伙伴愿意用Python进行答题。最近我们的一个粉丝交流群,有一位同学跟我分享了他面试的经历。小李学了Python大概有2年多了,他跟我讲了前段时间面试某杭州大厂的一道面试题,注意是面试题,不是笔试卷。

现场让你手写代码,压力山大啊~~也许是因为紧张的原因,也许是因为自己算法基础底子不深的原因,反正现场憋了很久,没有憋出来。到底是什么样的一个算法题呢,一起来看一下。

1

面试的题目

题目:

假设你手上有面值1块,2块,5块各若干张纸币,你现在需要支付给商家6元钱,请问你有多少种组合,列出每一种组合?

要求:

1).在白板上手写代码或者直接在电脑上写

2).分析你的算法,如何优化

3).对搜索的结果进行分析

看起来这个问题似乎很简单,就是一个空间组合搜索,然后加起来的面值为6即可,但是现场面试给你思考的时间,不会超过1分钟。小李当时就心里咯噔一下,leetcode的题目少刷了,其实面试之前也准备了,刷了一些算法题,但是还是手生了一些。

大家可以思考一下,如果是你的话,你先不看下面的答案,现场手写能写出来吗?

思路:

这个题目其实网上也很多类似的,就是钞票的选取方案而已,一般的解法都是递归。递归只要设计出口即可。如果我们的方案等于6元即退出,如果超过了6元就放弃,如果不足6元就继续添加更多的钞票即可。

bills是钞票面额的列表(假如为[1,2,5]),然后target是目标值(假如为6),然后填入一个空列表的方案 solution

  • 如果总金额等于target就打印solution;

  • 如果大于总金额就放弃;

  • 上面两种都不满足的时候,就是金额不够的情况,进行一个递归搜索,这里等于设计一个容器ways(用来存放方案,直接复制solution 列表),然后不断的加入一张钞票进行递归;

如果能现场写出来这个代码,并且运行成功,其实还是蛮厉害的,走到这一步,相信至少能拿到及格的分数了。但是面试官会进行第二次的提问,你觉得这个算法哪里有问题,怎么解决?

确实这个里面有很多重复的方案,比如[1,1,1,1,2]和[1,1,1,2,1]就是完全重复的,我们需要取重复。

2

二次优化

很明显上面的搜索是大而全的,就是有很多浪费的空间,如果我们的搜索的样本很大的话,就会有很多浪费的空间,这样的效率肯定是低的,如何优化呢?

有的同学说可以保存结果然后进行取重复,但是这样要等整个的结果出来才行;有没有办法在搜索空间算法上动手脚呢?

我们来看一些优化后的代码:

是不是过滤了很多重复的方案,我们在搜索的方案里面加一个新参数bigger,就是当前的已经生成的最高的面额,在搜索的过程中,我们只能append那些大于等于已经加入的最高的面额钞票,低的我们就不卖了。

当然还有其他的解决办法,其实如果回答出这个参数,相信会给面试官加分不少,说明在工作的时候,并不是一个只知道完成任务的,还是一个喜欢勤思考会优化代码的人。其实面试的时候回答出这一步,已经是可以拿到良好分了。

3

如何对搜索结果进行分析

上面的结果都是在通过print打印在内存里面,如果我们需要对整个的搜索的空间进行进一步的处理,比如我们有100种方案,我们需要保存到文件中或者数据库里面进一步的分析,如果把递归的结果提取出来呢?

第一种,简单粗暴:

我们直接用全局变量,在整个函数的外部加一个out=[],来存储所有的组合:

第二种,优雅的方式

全局变量固然简单,但是在生产的环境的项目里面,这肯定不是最佳的解法。最好的方法还是在函数内自己存储,然后我们只要在调用的时候获取即可。这里我们用Python里面的生成器yield来搞定。

通过yield来缓存递归过程的结果,是不是非常优雅。这个时候我们对所有的组合可以进行分析,比如我想找到用钞票最少的组合,就可以这样:

小编说两句:

其实整个这道面试题,如果是放在笔试题里面,相信大部分的同学都可以答出来,难度其实并不大。但是在面试的环节,就会难很多,一个紧张,二个思考的时间非常短,需要平时有深厚的积累!

建议参加大厂的面试,多多少少都要准备一下尤其是算法。一定要多刷一些leetcode的题目,不要照搬照套,一定要理解并且把代码学到肚子里去,实在不行,先把代码思路背下来,这样有备无患,毕竟临阵磨枪,不快也光!好了,希望今天的文章对大家有帮助。

近期原创热门:

程序员GitHub

由菜鸟学Python原班人马打造的公众号【程序员GitHub】开始啦!专注于分享GitHub上有趣的资源包括,Python,Java,Go语言,前端学习等优质的学习资源,分享程序员圈的新鲜趣事,热门干货,职场感悟。

点的“在看”,否则就看不到我了555
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值