处理以下问题,
问题,
给定m * n网格,允许一个向上或向右移动,找到两个网格点之间的不同路径。
我写了一个递归版本和一个动态编程版本,但是它们会返回不同的结果,并且有什么想法会出错?
源代码,
from collections import defaultdict
def move_up_right(remaining_right, remaining_up, prefix, result):
if remaining_up == 0 and remaining_right == 0:
result.append(''.join(prefix[:]))
return
if remaining_right > 0:
prefix.append('r')
move_up_right(remaining_right-1, remaining_up, prefix, result)
prefix.pop(-1)
if remaining_up > 0:
prefix.append('u')
move_up_right(remaining_right, remaining_up-1, prefix, result)
prefix.pop(-1)
def move_up_right_v2(remaining_right, remaining_up):
# key is a tuple (given remaining_right, given remaining_up),
# value is solutions in terms of list
dp = defaultdict(list)
dp[(0,1)].append('u')
dp[(1,0)].append('r')
for right in range(1, remaining_right+1):
for up in range(1, remaining_up+1):
for s in dp[(right-1,up)]:
dp[(right,up)].append(s+'r')
for s in dp[(right,up-1)]:
dp[(right,up)].append(s+'u')
return dp[(right, up)]
if __name__ == "__main__":
result = []
move_up_right(2,3,[],result)
print result
print '============'
print move_up_right_v2(2,3)
答案 0 :(得分:2)
动态编程版本的问题在于它没有考虑从多个向上移动('uu...'
)或多个向右移动('rr...'
)开始的路径。
在执行主循环之前,您需要为来自dp[(x,0)]
到x
和1
的每个remaining_right+1
填写dp[(0,y)]
来自y
1
至remaining_up+1
。
换句话说,替换它:
dp[(0,1)].append('u')
dp[(1,0)].append('r')
用这个:
for right in range(1, remaining_right+1):
dp[(right,0)].append('r'*right)
for up in range(1, remaining_up+1):
dp[(0,up)].append('u'*up)
答案 1 :(得分:2)
在版本2中,您应该从0开始for循环而不是1.从1开始,您将缺少可能首先遍历底行或最左列的排列。
将版本2更改为:
def move_up_right_v2(remaining_right, remaining_up):
# key is a tuple (given remaining_right, given remaining_up),
# value is solutions in terms of list
dp = defaultdict(list)
dp[(0,1)].append('u')
dp[(1,0)].append('r')
for right in range(0, remaining_right+1):
for up in range(0, remaining_up+1):
for s in dp[(right-1,up)]:
dp[(right,up)].append(s+'r')
for s in dp[(right,up-1)]:
dp[(right,up)].append(s+'u')
return dp[(right, up)]
然后:
result = []
move_up_right(2,3,[],result)
set(move_up_right_v2(2,3)) == set(result)
True
只是为了好玩......另一种方式:
from itertools import permutations
list(map(''.join, set(permutations('r'*2+'u'*3, 5))))