递归与记忆在楼梯问题中是自下而上的



将经典楼梯问题视为"戴维斯家里有很多楼梯,他喜欢一次爬1、2或3个楼梯。作为一个非常早熟的孩子,他想知道有多少种方法可以到达楼梯的顶部。

我的方法是使用带有递归的记忆作为

# TimeO(N), SpaceO(N), DP Bottom Up + Memoization
def stepPerms(n, memo = {}):
    if n < 3:
        return n
    elif n == 3:
        return 4
    if n in memo:
        return memo[n]
    else:
        memo[n] = stepPerms(n - 1, memo) + stepPerms(n - 2 ,memo) + stepPerms(n - 3 ,memo)
        return memo[n]

我想到的问题是,这个解决方案是自下而上还是自上而下。我的处理方法是,因为我们一直向下计算上 N 个值(想象一下递归树(。我认为这是自下而上的。这是对的吗?

通常,

Recoursion策略是自上而下的方法,无论它们是否有内存。底层算法设计是动态规划,传统上以自下而上的方式构建。

我注意到你用python编写了代码,python通常对深度还原不满意(少量是可以的,但性能很快就会受到影响,并且最大重新编码深度为1000 - 除非自从我读到它以来它被更改了(。

如果我们制作一个自下而上的动态 programmin 版本,我们可以摆脱这种重新定义,我们也可以认识到我们只需要恒定的空间量,因为我们只对最后 3 个值真正感兴趣:

def stepPerms(n):
    if n < 1: return n
    memo = [1,2,4]
    if n <= 3: return memo[n-1]
    for i in range(3,n):
        memo[i % 3] = sum(memo)
    return memo[n-1]

请注意逻辑简单得多,从 i 中分配的值比值少 1,因为位置从 0 开始而不是计数 1。

在自上而下的方法中,复杂模块被划分为子模块。所以这是自上而下的方法。另一方面,自下而上的方法从基本模块开始,然后进一步组合它们。

此解决方案的自下而上的方法将是:

memo{}
for i in range(0,3):
   memo[i]=i
memo[3]=4
for i in range(4,n+1):
  memo[i]=memo[i-1]+memo[i-2]+memo[i-3]

相关内容

  • 没有找到相关文章

最新更新