很经典的递归题,爬楼梯的方法=最后走1步+最后走2步,所以很容易就能写出递归算法。然而发现超时了,知道需要使用动态编程。其实上面的也是动态编程的思路,只不过动态编程将中间结果保存,这样其实遍历一次就能得到结果。
现在重新思考了一下动态编程和分治的相同于区别:
相同点:都需要寻找子问题,由子问题的解得到最终解
不同点:分治可能除了子问题,还需要额外的操作,有时候额外的操作时间复杂度甚至超过了子问题。分治一般不会保存中间结果,所以通常和递归结合使用。
动态编程必须明确找到子问题,并且子问题必须和原问题一样(目前遇到的都是一样的),动态编程必然存在一个递推关系(显示或者隐示的),显示的即可以直接用数学公式表示出来,隐示的需要找到一个DAG(有向无环图)。最终将问题转换为如何从起点走到终点的路径选择问题。
递归:
classSolution {
public:
int climbStairs(int n) {
if (n == 1)
return 1;
else if (n == 2)
return 2;
else
return climbStairs(n - 1) +climbStairs(n - 2);
}
};
动态规划:
class Solution {
public:
intclimbStairs(int n) {
intdp[200];
dp[1]= 1;
dp[2]= 2;
for(int i = 3; i <=n; i++)
dp[i]= dp[i - 1] + dp[i - 2];
returndp[n];
}
};
本文探讨了一个经典的递归问题——爬楼梯的不同方式。通过对比递归和动态规划两种方法,阐述了动态规划如何优化递归算法并提高效率。
326

被折叠的 条评论
为什么被折叠?



