用斐波那契数列来过度,结合油管上一个讲得比较好的tutorial,感受一下
递归-->记忆化搜索-->dp的过程。
以下是斐波那契数列的各个solution的实现。


public class FibDemo {
    // https://www.youtube.com/watch?v=1BAsAgdx7Ac
    // {1, 1, 2, 3, 5, 8, 13, ...}
    /*************************************************
     * 普通递归
     *************************************************/
    private long fib1(int n) {
        if (n < 1) return -1;
        if (n == 1 || n == 2) return 1;
        return fib1(n - 1) + fib1(n - 2);
    }
    /*************************************************
     * 记忆化搜索 (自上而下,人人为我)
     *************************************************/
    private Map<Integer, Long> memo;
    private long fib2(int n) {
        memo = new HashMap<>();
        return help(n, memo);
    }
    private long help(int n, Map<Integer, Long> map) {
        if (n == 1 || n == 2) return 1; // base case: 1和2直接返回
        if (map.containsKey(n)) return map.get(n); // 先查表,表中有则直接返回
        long res = help(n - 1, memo) + help(n - 2, memo); // 表中无,计算之
        map.put(n, res); // 计算结果放入表中,方便下次查询
        return res;
    }

    /*************************************************
     * DP (自下而上,我为人人)
     *************************************************/
    private long fib3(int n) {
        long[] dp = new long[n + 1]; // 用dp记录结果
        dp[1] = 1;
        dp[2] = 1;
        // 依次计算并填表
        for (int i = 3; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n]; // 直接返回
    }

    public static void main(String[] args) {
        FibDemo f = new FibDemo();
        int n = 45;
        long time = System.currentTimeMillis();
        System.out.println("普通递归结果:\t\t" + f.fib1(n) + ", 耗时" + (System.currentTimeMillis() - time));
        time = System.currentTimeMillis();
        System.out.println("记忆化搜索结果:\t" + f.fib2(n) + ", 耗时" + (System.currentTimeMillis() - time));
        time = System.currentTimeMillis();
        System.out.println("DP结果:\t\t\t" + f.fib3(n) + ", 耗时" + (System.currentTimeMillis() - time));
    }
}
普通递归结果:        1134903170, 耗时3255
记忆化搜索结果:    1134903170, 耗时1
DP结果:            1134903170, 耗时0

Process finished with exit code 0

proheart
41 声望20 粉丝

Developer, Java & Android