对于我无法解决的测验,我有以下问题:
给定一个树代表(5, (3, (20, (6, None, None), None), None), (10, (1, None, None), (15, (30, None, (9, None, None)), (8, None, None))))
,其中第一个项目是节点,第二个项目是左分支树,第三个项目是右分支树,找到最大的锯齿形(改变方向的选项)树)。
所以这棵树从5开始,向左移动到3或从右移到10,从3开始向左移动到20(它不能向右移动,右边是None
)。从10步行,它可以左转到1,或者右转到15等等。
我失败了,因为我甚至在递归走树时遇到了问题。我无法确定如何选择向左或向右走,当在树上走第二,第三等时间时,怎么知道它之前走过那条路?
我在这里
class Tree(object):
def __init__(self, zigzags, node, left, right):
self.zigzags = zigzags
self.node = node
self.left = left
self.right = right
TREE = (5, (3, (20, (6, None, None), None), None), (10, (1, None, None), (15, (30, None, (9, None, None)), (8, None, None))))
def walk_tree(tree, current_direction='l', zigzag_count=0, this_path=''):
left = tree[1]
right = tree[2]
print('left:')
print(left)
print('right:')
print(right)
print('zigzag_count:')
print(zigzag_count)
possible_left_path = this_path + 'l' # say like 'lrl'
possible_right_path = this_path + 'r' # say like 'lrr'
if left:
if current_direction == 'r':
zigzag_count += 1
return walk_tree(left, 'l', zigzag_count)
elif right:
if current_direction == 'l':
zigzag_count += 1
return walk_tree(right, 'r', zigzag_count)
else:
return zigzag_count
count = walk_tree(TREE)
print(count)
我认为走在左侧然后停了下来:
$ ./exam_question_2.py
left:
(3, (20, (6, None, None), None), None)
right:
(10, (1, None, None), (15, (30, None, (9, None, None)), (8, None, None)))
zigzag_count:
0
left:
(20, (6, None, None), None)
right:
None
zigzag_count:
0
left:
(6, None, None)
right:
None
zigzag_count:
0
left:
None
right:
None
zigzag_count:
0
0
预期答案是2,向右,向右,向左,向右走。
我想尝试解决之字形只是为了学习,但我想知道如何以这种格式递归地遍历这个二叉树,并知道我何时改变行走(当我再次从顶部开始)时,如果可能的话,背后有一些理论。我更喜欢Python或JavaScript中的一个例子。
答案 0 :(得分:4)
这是一个典型的分而治之的问题。给定一个带子节点的节点,该节点的之字形得分是具有最高之字形得分的子节点(如果达到该子节点需要更改方向,则添加1):
2013-05-14
当左侧节点可用时,您的代码从未被视为正确的路径。
这会产生您的预期路径:
def zigzagscore(node):
left, right = node[1:]
left_zigzag, left_path = 0, ''
if left is not None:
left_zigzag, left_path = zigzagscore(left)
if left_path.startswith('r'):
# We zigged for left
left_zigzag += 1
left_path = 'l' + left_path
right_zigzag, right_path = 0, ''
if right is not None:
right_zigzag, right_path = zigzagscore(right)
if right_path.startswith('l'):
# We zagged for right
right_zigzag += 1
right_path = 'r' + right_path
if left_zigzag > right_zigzag:
return left_zigzag, left_path
else:
return right_zigzag, right_path
答案 1 :(得分:1)
采用递归方法,您可以声明以下规则:
当前节点的最长曲折,如果从左边到达,则是最长的左曲折和最长的右曲折加1之间的最长曲折;相反,如果从右边到达。
根节点的规则不同,因为不能从任何一方到达。
def Length(Node, FromLeft):
if Node == None:
return 0
return max(Length(Node.Left, True) + (1 if not FromLeft else 0), Length(Node.Left, False) + (1 if FromLeft else 0))
print max(Length(Root.Left, True), Length(Root.Right, False))
我没有使用之字形,但当然这是可行的。