迭代算法中的递归算法

时间:2016-03-01 20:38:12

标签: algorithm recursion iteration

如何将以下递归算法转换为迭代算法?

QueryParameters

本质上,该算法计算如下:

count(integer: n)
  for i = 1...n
    return count(n-i) + count(n-i)
  return 1

3 个答案:

答案 0 :(得分:1)

这不是尾递归,因此将其转换为迭代并非易事。

但是,通过推送到堆栈而不是递归,可以很容易地使用堆栈和循环来模拟递归。

stack = Stack()
stack.push(n)
count = 0
while (stack.empty() == false):
  current = stack.pop()
  count++
  for i from current-1 to 1 inclusive (and descending):
     stack.push(i)
return count

另一种解决方案是使用Dynamic Programming进行,因为您不需要多次计算同一事物:

DP = new int[n+1]
DP[0] = 1
for i from 1 to n:
  DP[i] = 0
  for j from 0 to i-1:
    DP[i] += DP[j]
return DP[n]

请注意,您甚至可以通过记住“到目前为止的总和”来优化它以在O(n)而不是O(n^2)中运行:

sum = 1
current = 1
for i from 1 to n:
  current = sum
  sum = sum + current
return current

最后,这实际上总结为您可以轻松预先计算的内容:count(n) = 2^(n-1), count(0) = 1(您可以通过查看我们拥有的最后一个迭代解决方案来怀疑它...)

base:count(0)自动产生1,因为未达到循环体。
假设:T(k) = 2^(k-1)适用于所有k < n

证明:

T(n) = T(n-1) + T(n-2) + ... + T(1) + T(0) = (induction hypothesis)
     = 2^(n-2) + 2^(n-3) + ... + 2^0 + 1 = 
     = sum { 2^i | i=0,...,n-2 } + 1 = (sum of geometric series)
     = (1-2^(n-1)/(1-2)) + 1 =  (2^(n-1) - 1) + 1 = 2^(n-1)

答案 1 :(得分:0)

如果您以下列递归方式定义问题:

count(integer : n)
    if n==0 return 1 
    return count(n-1)+count(n-1)

转换为迭代算法是向后归纳的典型应用,您应该保留以前的所有结果:

count(integer : n):
  result[0] = 1

  for i = 1..n
     result[i] = result[i-1] + result[i-1]

  return result[n]
很明显,这比它应该更复杂,因为重点是向后诱导。我可以积累到一个地方,但我想提供一个更普遍的概念,可以扩展到其他情况。在我看来,这个想法更加清晰。

在关键思想明确后,可以改进伪代码。实际上,有两个非常简单的改进仅适用于这种特定情况:

  • 而不是保留所有先前的值,只需要最后一个值
  • 不需要两个相同的电话,因为没有预期的副作用

超越,可以根据函数的定义来计算,count(n)= 2 ^ n

答案 2 :(得分:-1)

声明return count(n-i) + count(n-i)似乎等同于return 2 * count(n-i)。在那种情况下:

count(integer: n)
  result = 1
  for i = 1...n
    result = 2 * result
  return result

我在这里缺少什么?

相关问题