递归与动态规划的不同

递归与动态规划的不同

递归与动态规划是两个十分基本的算法,它们使用的思路都是分而治之(将一个大问题拆解成一个小问题),我在刚开始学算法时,也是不明白这两者有什么不同,在经过这么久的学习后,我也是对此有了自己的理解(如有不对,欢迎指正)。

下面便是我觉得,递归和动态规划的2个不同:
1.递归是从上而下(从大问题到小问题),而动态规划是由下而上(先解决小问题最后到大问题);
2.动态规划会储存每个小问题的结果,从而它的计算速度会比递归要快。(代价是动态规划的空间复杂度更高,即用空间换取的时间)。

现在大家可能还不是很理解上面两点,让我举个例子来说明一下:
斐波那契数列。
在数学上,斐波那契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 3,n ∈ N*),即:新的一项等于前两项之和
即指的是这样一个数列:1、1、2、3、5、8、13、21、34…

下面让我们来求第n项的斐波那契数列的值:
这是一个经典的递归和动态规划问题,下面让我来用Python代码来演示这两种算法,希望大家通过代码可以理解我说的这两者的不同

递归:

def recur_F(n):

    if n == 1 or n == 2:  # 递归结束条件
        return 1

    return recur_F(n-1) + recur_F(n-2)  # 递归

可以看出,递归是将大n由上而下,逐渐拆解成2的n次方个小问题,这样的缺点就是,有些值会重复计算,例如,输入n=5,那它会将n=3计算两遍(第一次5变成4和3的时候一次,第二次4拆解成3和2的时候一次)。如下图所示,2和1标红代表递归结束,
在这里插入图片描述
这样当n比较大的时候,就会多算很多次没有必要的运算,自然时间就慢了

动态规划:

def dp_F(n):

    res = [0] * n  # 用来记录 n = [1,n] 的全部值

    res[0], res[1] = 1, 1  # 第一位和第二位都为1

    for i in range(2, n):
        res[i] = res[i-1] + res[i-2]  # 从 n=3 开始向后更新

    return res[n-1]

可以看出,动态规划与递归的最大不同就是它创建了一个数组(空间),来储存后面可能要用到的所有值,这样,就可以避免重复运算的过程,因为后面要用到的值都可以直接来数组里取。还有一点不同就是,它是从前往后进行运算的。

当然,当n比较大时,动态规划需要的空间就很多了,我们可以进行一下优化:

def dp_F_s(n):

    if n == 1 or n == 2:
        return 1

    fn_1 = 1
    fn_2 = 1  # 只需要存储 每次运算需要的两位数值就行

    cur = 0

    for i in range(3, n+1):
        cur = fn_1 + fn_2  # 后一项 = 前两项之和

        fn_1 = fn_2
        fn_2 = cur  # 更新这两位数值

    return cur

这样,就可以减少动态规划的空间复杂度。当然,这里的思路还是从前往后运算,只不过它所需要的空间变成了2。(之前是n)

**
总结一下,这两者的两个不同:

1.递归是由上而下,动态规划是从下而上;

2.动态规划的运算速度更快。

**

以上便是个人理解的递归与动态规划的不同,如有错误,欢迎指正!

  • 25
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
递归、回溯和动态规划都是常用的问题求解方,它们在不同的场景下有不同的应用。 递归(Recursion)是一种通过将问题分解为更小的子问题来求解的方递归函数会重复调用自身,直到达到某个终止条件。递归通常用于解决问题的定义是自身的情况,例如计算斐波那契数列、求解二叉树的深度等。递归的实现简单直观,但在某些情况下可能会导致效率低下或者堆栈溢出的问题。 回溯(Backtracking)是一种通过尝试所有可能的情况来求解问题的方。回溯算法通常用于求解排列组合、搜索问题,如八皇后问题、组合总和等。回溯算法通过遍历所有可能的选择并进行回退,以找到所有满足条件的解。回溯算法可以通过剪枝操作来减少不必要的尝试,提高效率。 动态规划(Dynamic Programming)是一种通过将问题划分为若干个重叠子问题,并保存子问题的解来避免重复计算的方动态规划通常用于求解最优化问题,如最长公共子序列、最短路径、背包问题等。动态规划算法通过状态转移方程和边界条件来确定子问题之间的关系,并按照一定的计算顺序求解子问题,最终得到原问题的解。动态规划算法的时间复杂度通常较低,可以大大提高算法的效率。 总结来说,递归是一种问题分解的方,回溯是一种穷举搜索的方动态规划是一种优化求解的方。它们在不同的问题场景下有着各自的应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值