斐波那契数列
1、暴力递归
斐波那契数列的数学形式就是递归的,写成代码就是这样:
int fib(int N) {    
    if (N == 1 || N == 2) return 1;    
    return fib(N - 1) + fib(N - 2);
}
2、带备忘录的递归解法
一般使用一个数组充当这个「备忘录」,当然你也可以使用哈希表(字典),思想都是一样的。
public int Fib(int n)
{
    if (n < 1) return 0;
    var array = new int[n + 1];
    return Helper(array, n);
}
public int Helper(int[] memo, int n)
{
    if (n == 1 || n == 2) return 1;
    //已经计算过
    if (memo[n] != 0) return memo[n];
    memo[n] = Helper(memo, n - 1) + Helper(memo, n - 2);
    return memo[n];
}
3、dp 数组的迭代解法
有了上一步「备忘录」的启发,我们可以把这个「备忘录」独立出来成为一张表,就叫做 DP table 吧,在这张表上完成「自底向上」的推算岂不美哉!
public int Fit(int n)
{
    var dp = new int[n + 1];
    //base case
    dp[1] = dp[2] = 1;
    for(var i = 3; i <= n; i++)
    {
        dp[i] = dp[i - 1] + dp[i - 2];
    }
    return dp[n];
}
优化
当前状态只和之前的两个状态有关,其实并不需要那么长的一个 DP table 来存储所有的状态,只要想办法存储之前的两个状态就行了。所以,可以进一步优化,把空间复杂度降为 O(1):
public int Fit(int n)
{
    if (n == 2 || n == 1) return 1;
    int prev = 1, curr = 1;
    for(var i = 3; i <= n; i++)
    {
        var temp = prev + curr;
        prev = curr;
        curr = temp;
    }
    return curr;
}

                
            
        
浙公网安备 33010602011771号