斐波那契数列 本身就是一个递归的过程(动态规划的问题)
如果求第n个数时,返回的参数是n-1以及n-2。
普通的递归写法:
def count(self,n):#when we use recursion, we may use one result too many times, which leads to a high complexity
if n ==0:
return 0
if n == 1:
return 1
else:
return self.count(n-1)+self.count(n-2)
咋一看是没问题的,但是测试发现,当n偏向很大的时候,产生了太多的重复过程。比如n-3在n-2以及n-1的求解过程中都有用到。然后它再调用前面的时候也会重复调用,这样对于初始的0 和 1,可能会产生相当大的调用情况。我们在递归时 也要做到尽量避免重复!
这时候可以想到的想法就是 正向迭代,得到最终结果,这样每个参数都只用到了两次。
代码:
def count2(self,n):
if n == 0:
return 0
if n == 1:
return 1
else:
res1 = 1
res2 = 0
while n>1:
res1,res2 = res1+res2,res1
n-=1
return res1
回溯就是一种带重复的递归!(正常的递归依然可能会产生重复的情况)
正向迭代一般不会产生多余的过程,但是对于很多情况,正向迭代很难找到需要的target,或者找不到停止的边界点。(例如上一篇中的掷骰子,可以试试正向迭代的情况,其递归情况就会产生重复操作)
递归的改进:
同样可以参考上一篇的内容。做一个字典,存储已经产生的结果。存在则直接调用,不存在则添加进去。
改进后的递归代码:
def count0(self, n):
temp = {}
def count3(n): # when we use recursion, we may use one result too many times, which leads to a high complexity
if n == 0:
temp[0] = 0
return 0
if n == 1:
temp[1] = 1
return 1
else:
if n - 1 in temp:
a = temp[n - 1]
else:
a = count3(n - 1)
temp[n-1] = a
if n - 2 in temp:
b = temp[n - 2]
else:
b = count3(n - 2)
temp[n-2] = b
return a + b
return count3(n)
完整的代码以及测试方式如下:
import time
def singleton(func):
def count_time(*args):
a = time.time()
res = func(*args)
b =time.time()
print('time',b-a)
return res
return count_time
class Solution:
#@singleton
def count(self,n):#when we use recursion, we may use one result too many times, which leads to a high complexity
if n ==0:
return 0
if n == 1:
return 1
else:
return self.count(n-1)+self.count(n-2)
@singleton
def count2(self,n):
if n == 0:
return 0
if n == 1:
return 1
else:
res1 = 1
res2 = 0
while n>1:
res1,res2 = res1+res2,res1
n-=1
return res1
def count0(self, n):
temp = {}
def count3(n): # when we use recursion, we may use one result too many times, which leads to a high complexity
if n == 0:
temp[0] = 0
return 0
if n == 1:
temp[1] = 1
return 1
else:
if n - 1 in temp:
a = temp[n - 1]
else:
a = count3(n - 1)
temp[n-1] = a
if n - 2 in temp:
b = temp[n - 2]
else:
b = count3(n - 2)
temp[n-2] = b
return a + b
return count3(n)
su = Solution()
a = time.time()
res1 = su.count0(30)
b = time.time()
print('time', b - a)
print(res1)###normal recursion
res2 = su.count2(100)
print(res2)###iteration
a = time.time()
res3 = su.count(30)
b = time.time()
print('time', b - a)
print(res3)##improved recursion
tips:
重要的想法:
避免重复!!!在循环的过程中