面试题:
1、试输出斐波那契数列的前10项,即1、1、2、3、5、8、13、21、34、55。
方法1:使用递归
// 创建一个函数,功能是返回下标为 n 的这项的数字
function fib (n) {
// 看下标 n 是不是 0 或者是不是 1, 如果是,就返回常数 1,如果不是就递归
var v = n === 0 || n === 1 ? 1 : fib(n - 1) + fib(n - 2)
return v
}
// var num = fib(5)
// console.log(num)
for (let i = 0; i <= 9; i++) {
console.log(fib(i))
}
方法2:使用数组
var arr = [1, 1]
while (arr.length < 10) {
arr.push(arr[arr.length - 1] + arr[arr.length - 2])
}
console.log(arr) // [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
2、然后请思考,代码是否有大量重复的计算?应该如何解决重复计算的问题?
这张图表示了执行顺序,每计算一个结果需要从 fib(0) 和 fib(1) 开始往上计算,这样就会重复很多计算结果
声明一个缓存对象,把每次传入的 n 作为 key,计算结果作为 value ,储存到 cache 对象中,下次遇到 相同的 n , 就不再重新计算,而是直接使用之前计算出的结果,这样可以省略计算次数。
缓存对象格式是这样的: {2: 2, 3: 3, 4: 5, 5: 8, 6: 13, 7: 21, 8: 34, 9: 55}
// 缓存对象,把每次传入的 n 作为 key,计算结果作为 value ,储存到 cache 对象中,下次遇到 相同的 n , 就不再重新计算,而是直接使用之前计算出的结果,这样可以省略计算次数
var cache = {}
// 创建一个函数,功能是返回下标为 n 的这项的数字
function fib (n) {
console.count('运行次数是:')
// 判断缓存对象中有没有这个属性,如果有,直接用n对应的计算结果值
if (cache.hasOwnProperty(n)) {
return cache[n]
}
// 缓存对象咩有这个值
// 看下标 n 是不是 0 或者是不是 1, 如果是,就返回常数 1,如果不是就递归
var v = n === 0 || n === 1 ? 1 : fib(n - 1) + fib(n - 2)
// 计算结果写入缓存
cache[n] = v
return v
}
// var num = fib(5)
// console.log(num)
for (let i = 0; i <= 9; i++) {
console.log(fib(i))
}
console.log(cache) // {2: 2, 3: 3, 4: 5, 5: 8, 6: 13, 7: 21, 8: 34, 9: 55}