【发布时间】:2019-03-18 04:10:03
【问题描述】:
我在一次模拟面试中遇到了一个问题,我必须找出一个给定节点已经着火后二叉树会完全烧毁多长时间。
"一棵二叉树从叶子节点开始燃烧。什么是 时间(1秒从一个节点燃烧到另一个节点)获取整棵树所需的时间 烧了?火势会从一个节点蔓延到所有路径。"
假设你有一棵像这样的树,其中 N 是着火的节点。这是 发生在第一秒,其中秒是 s,所以在第零个 s:
1
/ \
1 1
/ \ \
1 1 1
/ \ \
1 N 1
\
1
一秒钟后,树将更新为更多已烧毁的节点。 下一秒 (s + 1) 的示例将是这样的:
1
/ \
1 1
/ \ \
1 N 1
/ \ \
1 N 1
\
1
下一秒(s + 2)的例子会是这样的:
1
/ \
N 1
/ \ \
1 N 1
/ \ \
N N 1
\
1
现在在第三秒 (s + 3) 将是这样的:
N
/ \
N 1
/ \ \
N N 1
/ \ \
N N 1
\
1
同样的模式,树会在(s + 7)中被烧毁
N
/ \
N N
/ \ \
N N N
/ \ \
N N N
\
N
在了解了一点之后,我做了一个小的研究来弄清楚如何去做。我发现了这个很酷的article 并跟进并实施了背后的想法。
我的方法是找到树的直径和高度,以寻找最远的节点到节点。但是,当我实现我的功能时,我只得到 starting node 的结果到 given node 的末尾,而不检查以前的父节点。这是我在 Python 3 中的实现:
# Tree class
class Node:
def __init__(self, key):
self.left = None
self.right = None
self.value = key
# Maximum height of a tree
def maxHeight(root):
if root is None:
return 0
else:
return 1 + max(maxHeight(root.left), maxHeight(root.right))
# Diameter of the tree
def maxDiameter(root):
how_long = 0
if root is None:
return 0
else:
root_diameter = maxHeight(root.left) + maxHeight(root.right)
left_diameter = maxDiameter(root.left)
right_diameter = maxDiameter(root.right)
how_long = max(max(left_diameter, right_diameter), root_diameter)
return how_long
# Sample code
root = Node(1)
root.left = Node(1)
root.right = Node(1)
root.left.left = Node(1)
root.left.right = Node(1)
root.left.right.left = Node(1)
root.left.right.right = Node(1)
root.right.right = Node(1)
root.right.right.right = Node(1)
root.right.right.right.right = Node(1)
print ("Starting from the given node, it will take %ds to burn the whole tree" % (maxDiameter(root.left.right)))
此示例的预期输出应为 6s(从给定节点的 0s 开始)。但同样,我没有得到树的全部范围。根据我自己的理解,它必须适用于所有情况。那么,什么搜索在这里会有所帮助,DFS 或 BFS?我认为考虑到这一点将引导我找到我的解决方案,但又一次。任何反馈表示赞赏:)
【问题讨论】:
-
问题说火灾始于叶节点,但您的示例始于非叶节点。
-
还有,最后一秒是怎么回事?您烧毁了 3 个未连接到最近源的节点
-
我猜最长的应该是根的权重 + 对共同祖先权重最高的叶子的权重,以秒为单位的时间将是加在一起的时间。将在更短的时间内到达每个其他节点。
-
你是对的@m69
-
在我做了一些更改后修复了我的示例@Yuca。
标签: python-3.x algorithm class recursion binary-tree