风和日丽 2019-06-27
值此高考来临之际,闲不住的我又双叒叕出发去面试攒经验了,去了公司交待一番流程后,面试官甩给了我一张A4纸,上面写着一道js算法笔试题(一开始我并不知道这是在考察js算法),上面写着“1、1、2、3、5、8......,求第n个数的值”
不得不承认,当时我第一眼看这道题大脑里是懵逼的。后来才想起来,这不就是数学题里的那个斐波那契(肥婆纳妾)数列么!从第三个数开始,每个数都是前两个数的和。
能get到这个点,你已经成功了一半了。另一半就是需要你将数学公式逻辑转变成js程序逻辑。
那其实这个问题还可以换个问法:实现一个函数,输入一个数字n能返回斐波那契数列的第n个值。
首先,思路很重要,让我们一起来分析一下,大概的思路是这样的:
首先我们要把特殊的部分给独立出来做个判断,哪些数字是特殊的呢?很明显是斐波那契数列的前两项,而斐波那契数列的前两项都为1。然后定义三个变量,firstNum、secondNum、total,分别代表着第一个数字,第二个数字,还有他们俩之和。
然后通过一个for循环遍历,将firstNum加上secondNum的结果赋值给total,然后将secondNum的value赋值给firstNum,把total的value赋值给secondNum,以此根据传入的n来不断地循环叠加,达到想要的total值,最后return返回出去。
思路说完后,让我们用js把它实现出来:
// 可能是最普通的解法 var series = function (n) { var sum = [0, 1]; if(n < 2) { return sum[n]; } var firstNum = 0; var secondNum = 1; var total = 0; for (var i = 2; i<= n; i++) { total = firstNum + secondNum; firstNum = secondNum; secondNum = total; } return total; }
记住,面试官与咱们应聘者的思维不同,你应聘的时候你大部分时间是在想,这道题我会不会做,能不能做出来,而他们想的是这道题的最优解。
前端的工作,“最优解”其实是一种自我追求进步的表现。
除了以上这种办法,还有什么更好的解决办法吗?答案是有的。
先来看看迭代的解法
var series = function (n) { var feipo = [0,1]; for(var i=2;i<=n;i++){ feipo[i] = feipo[i-1] + feipo[i-2] } return feipo[n]; } // console.log(series(6));
再来看看递归的解法
var series = function (n) { if(n >= 2) { return series(n-1) + series(n-2) }else { return n; } } // console.log(series(6));
究竟哪个才是最优解,相信看完文章的你们已经有了答案。
可能你们会问:
那闰土你在笔试时做出来了么?
你猜~
目前为止我也参加过很多次大大小小的前端面试,确实也听说过有不少面试官会问到一些算法。通常会涉及的,是链表、树、字符串、数组相关的知识。前端面试对算法要求不高,似乎已经是业内的一种共识了。虽说算法好的前端面试肯定会加分,但是仅凭常见的面试题,而不去联系需求,很难让人觉得,算法对于前端真的很重要。
直到有这么一天,太原这家公司的前端leader给我出了这么一道js算法题之后,还跟我聊了很多内容,与我固有的思维产生了强烈的碰撞。面试官还跟我讲,他们公司的技术总监是微软出身,很注重算法这块,他当初应聘进来的时候,也是考察的算法。
虽然这次面试被pass了,但是我认为工程师都应该学习算法,我觉得那不仅仅是对软件工程思想的培养,更是一种对心智的锻炼。
文章预告:更多的前端面试分享我都会第一时间更新在我的公众号<闰土大叔>里面,欢迎关注!
动态规划有时被称为递归的相反的技术。动态规划方案通常使用一个数组来建立一张表,用于存放被分解成众多子问题的解。当算法执行完毕,最终的解法将会在这个表中找到。今天我们先从我们最熟的斐波那契数列数列开始。