来,一起捋一捋 “递归——记忆化搜索——动态规划” 三者之间的关系

0 1 2 3 5
递归方法如果用二叉树画出递归的结构图就会发现,出现了很多重复运算,比如说fib(100)=fib(99)+fib(98)。
记忆化搜索通过新增一个列表容器来记录已经计算过的内容,这样就避免了重复运算,提高了效率,但是很明显有空间换时间的味道。
动态规划通过两个变量保存目标之前两个的内容就可以了,这样省略了空间开销,也提高了效率。动态规划有个状态转移过程,一般可以用一个等式来表示,当然这里可以表示为f(n) = f(n-1)+f(n-2),所以求解动态规划问题,可以先找到这个状态转移方程。
但是必须声明,这里的动态规划相对比较简单,真正的动态规划是有表结构可以推算的。
很明显这里的递归和记忆化搜索都用的是自上而下,动态规划是自下而上,二者的区别很明显,自上而下的话由于真正的值在最底层,所以上方的值无法求出,就需要一步步推到最下层,然后再把变量向上传递,最终得出结果,其中有自上而下推导,再自下而上传递变量,两个过程。
但是自下而上的话,直接从底层开始,一步步推导到目标,变量也同时自下而上传递,得出最终的结果。
但是众所周知,递归有自下而上的,也有自上而下的,这里我们用了自上而下,那么有没有自下而上的呢?当然有啦删除线格式

归并排序

自上而下的递归

对一个数组(str)选中一个中间位置(mid=(start+end)/2),分别进行左递归(mergeSort(str,start,mid,length)),右递归(mergeSort(str,mid+1,end,length)),在回朔的时候分别对以中间为分割的数组进行排序(merge(str,start,end,mid)),此时是一个归并的过程,这是自上而下的方法。

自下而上的递归

自下而上归并其实就是自上而下的时候的回朔过程,先对每一个数字排序,在两两排序,在对结果两两排序,直到完成。!

1.递归

def  fab(n):
  if n<=1:
    return n
  return fab(n-1)+fab(n-2)

2.记忆化搜索

def  fab(n):
  memo = [-1]*(n+1)
  def fib(n):
    if n<=1:
      memo[n] = n
    if memo[n]==-1:
      memo[n] = fab(n-1)+fab(n-2)
    return memo[n]
  return fib(n)

3.动态规划

def climbStairs(self, n):
    a = b = 1
    for _ in range(n):
        a, b = b, a + b
    return a
  

比较三者的区别:显然动态规划中没有递归,只需要推导出状态转移方程即可,而递归和记忆化搜索都需要递归调用,但是记忆化搜索明显减少了重复计算,至于效果当然是动态规划最好,记忆化搜索次之,递归效果最差。空间和时间效率方面也是相同的排列顺序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值