问题描述
查找仅通过向下或向右从栅格的一个角到达另一角的方法。我提出了使用递归来解决问题的初步思路:
def find_num_of_ways(x: int,y: int):
if x == 0 or y == 0:
return 1
return find_num_of_ways(x - 1,y) + find_num_of_ways(x,y - 1)
当x和y增加时,这可能是堆栈溢出。想要找到一种更好的重构方法,一种是转换为尾递归。但是给定签名中的2个变量,那么如何累加结果以使其尾部递归?
解决方法
我对此的分析是,计算答案要花费很长时间,以至于您在堆栈溢出之前就走了很长时间。我建议我们完全删除递归,并将其作为盒子和球的组合问题来做
(x + y - 1)!
------------
y!(x - 1)!
加上相反的内容:
(y + x - 1)!
------------
x!(y - 1)!
即Python方式:
from math import factorial as f
def find_num_of_ways(x,y):
return f(x + y - 1) // (f(y) * f(x - 1)) + f(y + x - 1) // (f(x) * f(y - 1))
print(find_num_of_ways(10,10))
输出
> python3 test.py
184756
>
在性能方面,对于参数:
find_num_of_waysTail(13,14)
在我的机器上,OP的原始递归解决方案花费9秒,@ Mike67的计数器解决方案花费约12秒,而我上面的解决方案花费约0.05秒。全部产生结果20058300。
,由于所有路径都在同一点结束,因此您只需计算触摸最后一点的次数即可。
#### Recursion ####
def find_num_of_ways(x: int,y: int):
if x == 0 or y == 0:
return 1
return find_num_of_ways(x - 1,y) + find_num_of_ways(x,y - 1)
ttl = find_num_of_ways(10,10)
print("Recursion",ttl)
#### Counter ####
ttl = 0
def find_num_of_waysCtr(x: int,y: int):
global ttl
if x == 0 or y == 0:
ttl += 1
return
find_num_of_waysCtr(x - 1,y)
find_num_of_waysCtr(x,y - 1)
find_num_of_waysCtr(10,10)
print("Counter ",ttl)
输出
Recursion 184756
Counter 184756