难易程度:Hard
是否重点:10 分
掌握程度:轻松写出二叉树遍历、八皇后、背包问题、DFS 的递归代码
- 斐波那契数列、求阶乘
- 归并排序、快速排序、二叉树的遍历、求高度
- 回溯八皇后、背包问题
练习:
剑指 Offer 10- I. 斐波那契数列
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1
求余运算 (a + b) % p = (a % p + b % p) % p
(5 + 14) % 3 = 1 = (
5 % 3 + 14 % 3) % 3
⚠️ n > 44后结果移除
n=0 => 1
n=1 => 1
n=2 => 2
特殊处理
if (n == 0 || n==1) return 1;
方法1: 递归(超时)
var fib = function(n) {
if (n < 2) return n;
return (fib(n-1) % 1000000007 + fib(n-2) % 1000000007) % 1000000007
};
方法2: 动态规划
var fib = function(n) {
if (n < 2) return n;
const P = 1000000007
let dp = new Array(n+1).fill(null)
dp[0] = 0
dp[1] = 1
for (let i = 2; i <= n; i++) {
dp[i] = (dp[i-1] % P + dp[i-2] % P) % P;
}
// console.log(dp)
return dp.pop();
};
改造: 迭代
var fib = function(n) {
if (n < 2) return n;
let P = 1000000007;
let a = 0, b =1;
for (let i = 2; i <= n; i++) {
[a, b] = [b%P, (a+b)%P]
}
return b
};
方法3: 尾递归
var fib = function(n) {
if (n < 2) return n;
return tail(n, 1, 1)
};
function tail (n, res1, res2) {
// console.log(n, res1, res2)
const P = 1000000007;
if (n == 1) return res1;
// if (n == 2) return res2;// 同上
return tail(n-1, res2 % P, (res1+res2)%P);
}
fib(8) // 21
第n位[0, 1, 1], 从1开始
若n位[1, 1, 2], 从0开始
function fiboTail(n, res1 = 1, res2 = 1) {
// console.log(n, res1, res2)
if (n == 0) return res1;
return fiboTail(n-1, res2, res1 + res2)
}
console.log(fiboTail(8)) // 34