读题
keyword1-斐波那契(Fibonacci)数列:
F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
思路
1.上来暴力点就是递归嘛,显然存在大量重复计算。
说一下递归
三板斧:https://mp.weixin.qq.com/s/mJ_jZZoak7uhItNgnfmZvQ
------明确函数功能
------递归结束条件:所谓递归,就是会在函数内部代码中,调用这个函数本身,关键是要找到小一号规模的子问题。
我们设计程序时, 这个传入参数 i 是我们为解决眼前问题时的规模 , i - 1 是小一号的问题的规模 . 比如: 我们令f(i) 为 某人花掉 i 元钱 . 那么f(i) 在自身 调用f(i - 1) 时相当于 自己先花掉1 元后 ,将剩下的 i - 1元钱给另一个人用. 显然, 钱不可能为负, 因此总有被花光的时刻(i = 0 时应当终止), 相应的, 重复自身调用也有终止的一刻 , 也即是说, 递归要有出口
怎么找?n变小(n=0,1,2)。
------找出函数的等价关系式
递归文章看这个包C:https://blog.csdn.net/Lagrantaylor/article/details/104117326
2.于是想到可以把算过的数据存下来,存在数组或者map(HashMap)里,称之为记忆递归法,显然需要额外的O(N)空间。
3.上面这个办法捞的一超时了,抄答案来一手动态规划
说一下动态规划,我感觉动态规划就是递归算法,再加上记忆功能,不知道理解有没有问题,因为感觉动态规划都需要子问题的递推关系。
先想递归
发现重复计算
通过记忆化等方法弄掉重复计算
最后看下能不能通过利用计算顺序来做到去掉递归用“刷表”方式直接顺序计算
动态规划看这个包C:Chttps://zhuanlan.zhihu.com/p/91582909
class Solution {
public:
int fib(int n) {
int dp[2] = {0, 1};
for(int i = 2; i < n + 1; i++){
dp[i & 1]=(dp[1]+dp[0])%1000000007;
}
return dp[n & 1];
}
};