递归会重复算
约 10 分钟
递归写起来漂亮,但有个大坑:同一个子问题会被重复计算很多遍。斐波那契数列最典型:
int fib(int n) {
if (n <= 2) return 1;
return fib(n - 1) + fib(n - 2); // 看着很美,其实很慢
}
问题在哪?算 fib(5) 要算 fib(4) 和 fib(3),而 fib(4) 又要算一遍 fib(3)……同一个 fib(3) 被反复展开。调用次数随 指数级膨胀,大约是 , 到 40 多就慢得跑不动了。
改用递推——从小往大一步步推,每个值只算一次:
int fib(int n) {
int a = 1, b = 1; // f(1), f(2)
for (int i = 3; i <= n; i++) {
int c = a + b; // 当前项
a = b; b = c; // 向前挪一格
}
return b;
}
这样只需 时间、 空间,快得多。
结论:能递推就别用朴素递归。如果非要用递归,就把算过的结果存进数组(记忆化),下次直接查表,也能降到 。考试里凡是“子问题重叠”的题,递推或记忆化往往是正解。
小纸条
递归和递推,哪个更省时间?
登录 后可看答案