我正在尝试解决欧拉问题18,我需要从上到下找出最大总数。我试图使用递归,但我坚持这个。
我想我之前没有提出我的问题。我试图通过递归实现的是找到最大数量路径的总和。我从三角形的顶部开始,然后检查条件是7 + findsum()更大或4 + findsum()更大。 findsum()应该找到它下面的数字之和。我将总和存储在变量'结果' 问题是我不知道这个递归函数的破坏情况。我知道当它到达子元素时它应该会中断,但我不知道如何在程序中编写这个逻辑。
pyramid=[[0,0,0,3,0,0,0,],
[0,0,7,0,4,0,0],
[0,2,0,4,0,6,0],
[8,0,5,0,9,0,3]]
pos=[0,3]
def downleft(pyramid,pos):#returns down left child
try:
return(pyramid[pos[0]+1][pos[1]-1])
except:return(0)
def downright(pyramid,pos):#returns down right child
try:
return(pyramid[pos[0]+1][pos[1]+1])
except:
return(0)
result=0
def find_max(pyramid,pos):
global result
if downleft(pyramid,pos)+find_max(pyramid,[pos[0]+1,pos[1]-1]) > downright(pyramid,pos)+find_max(pyramid,[pos[0]+1,pos[1]+1]):
new_pos=[pos[0]+1,pos[1]-1]
result+=downleft(pyramid,pos)+find_max(pyramid,[pos[0]+1,pos[1]-1])
elif downright(pyramid,pos)+find_max(pyramid,[pos[0]+1,pos[1]+1]) > downleft(pyramid,pos)+find_max(pyramid,[pos[0]+1,pos[1]-1]):
new_pos=[pos[0]+1,pos[1]+1]
result+=downright(pyramid,pos)+find_max(pyramid,[pos[0]+1,pos[1]+1])
else :
return(result)
find_max(pyramid,pos)
答案 0 :(得分:1)
编辑:我发现你在使用代码逻辑时遇到了麻烦。那么让我们来看看。
if
,然后在elif
),这非常昂贵。你应该只计算一次孩子的价值。所以结构应该是这样的:
function getScoreAt(x, y):
if at the end: return valueInTree(x, y)
valueLeft = getScoreAt(x - 1, y + 1)
valueRight = getScoreAt(x + 1, y + 1)
valueHere = min(valueLeft, valueRight) + valueInTree(x, y)
return valueHere
额外提示:
你是否意识到在Python中,负面索引会回绕到数组的后面?因此,如果您执行pyramid[pos[0]+1][pos[1]-1]
,您实际上可能会遇到pyramid[1][-1]
这样的元素,它位于金字塔行的另一侧。您可能期望的是,这会引发错误,但事实并非如此。
要解决您的问题,您应该添加显式绑定检查,而不是依赖try
块(try
块,因为这也不是一个很好的编程风格。)
答案 1 :(得分:1)
您的问题很大一部分就是您需要更多地递归 。你应该只是递归地调用find_max
两次,并且你需要一些基本逻辑来在最后一行之后停止。
试试这段代码:
def find_max(pyramid, x, y):
if y >= len(pyramid): # base case, we're off the bottom of the pyramid
return 0 # so, return 0 immediately, without recursing
left_value = find_max(pyramid, x - 1, y + 1) # first recursive call
right_value = find_max(pyramid, x + 1, y + 1) # second recursive call
if left_value > right_value:
return left_value + pyramid[y][x]
else:
return right_value + pyramid[y][x]
我更改了调用签名,使其具有单独的坐标值,而不是使用元组,因为这使得索引更容易编写。使用find_max(pyramid, 3, 0)
调用它,并删除全局pos
列表。我也摆脱了result
全局(函数返回结果)。
这种算法可以从记忆中受益匪浅,因为在更大的金字塔上,你可以多次计算中下区域的值。如果没有memoization,对于大金字塔大小,代码可能会非常慢。