斐波那契数列和零钱兑换

Posted d9e84208

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了斐波那契数列和零钱兑换相关的知识,希望对你有一定的参考价值。

斐波那契数列和零钱兑换

说到递归,就不得不提大名鼎鼎的斐波那契数列,这个最早接触应该还是高中数学的数列部分,后来学C语言的时候,老师讲递归就是举的这个例子。表达式如下:
技术图片

代码就是下面这个样子:

    public static int fib(int num) {
        if (num == 1 || num == 2) {
            return 1;
        }
        int a = fib(num - 1);
        int b = fib(num - 2);
//        return fib(num-1)+fib(num-2); 写在一行 调试看不清
        return a + b;
    }
    public static void main(String[] args) {
        int fib = fib(6);
        System.out.println(fib);
    }

执行过程就是这个样子:

技术图片

一直很困惑,到底是怎么执行的,直到遇到idea这个强大的工具,才算是比较清楚了。

技术图片

配合上面那个二叉树和这个debug的图,可以清楚的看到执行到什么位置了,每一次递归进去都会开一个新的Frames,见上图左下角。跟一遍就会发现,这个确实进行了很多重复计算。

于是动态规划出现了~

    public static int fib1(int num) {
        if (num == 1 || num == 2) {
            return 1;
        }
        int[] dp = new int[num + 1];
        // 初始化
        dp[1] = dp[2] = 1;
        // 将计算过的记下来,这样就大大减少了重复计算的内容
        for (int i = 3; i <= num; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[num];
    }

这样效率就大大提高了。

另一个类似的问题是零钱兑换,这个和斐波那契数列基本一样的。

技术图片

递归:

public class CoinChange {
    public static int coinChange(int target) {
        if (target == 1 || target == 2 || target == 5)
            return 1;
        if (target == 3 || target == 4)
            return 2;
        int a = coinChange(target - 1);
        int b = coinChange(target - 2);
        int c = coinChange(target - 5);
        return Math.min(a, Math.min(b, c)) + 1;
    }
    public static void main(String[] args) {
        int res = coinChange(40);
        System.out.println(res);
    }
}
    public static int coinChange1(int target) {
        int[] dp;
        if (target <= 5) {
            dp = new int[6];
        } else {
            dp = new int[target + 1];
        }
        // 初始化 
        dp[0] = 0;
        dp[1] = dp[2] = dp[5] = 1;
        dp[3] = dp[4] = 2;
        for (int i = 6; i <= target; i++) {
            dp[i] = Math.min(dp[i - 1], Math.min(dp[i - 2], dp[i - 5])) + 1;
        }
        return dp[target];
    }

以上是关于斐波那契数列和零钱兑换的主要内容,如果未能解决你的问题,请参考以下文章

C语言用递推和递归两种算法完成斐波那契数列的计算,给一下代码

python递归求斐波那契数列前10项

Go语言 斐波那契数列的解法

python代码实现斐波那契数列数列

编写一递归函数求斐波那契数列的前40项

用JAVA表示斐波那契数列 急急急!!!!