有树结构,例如
1
/ \
/ \
2 3
| / \
| / \
4 5 6
和必须在子树中的节点(叶子)集合,例如
[5, 6]
如何找到包含所有这些节点并从根元素开始的最小子树?像这样:
1
\
\
3
/ \
/ \
5 6
答案 0 :(得分:2)
基本上,您可以递归到叶子,并找到每个叶子是否需要它。当递归再次返回时,您可以看到是否需要任何后代。
这是执行此操作的伪代码:
def mark_needed_nodes(node, given_nodes):
# If a leaf, check if it is in given_nodes
if node is leaf:
node.needed = node in given_nodes
return node.needed
# It is not a leaf; check if any of the descendants is needed.
node.needed = False
for child in node.children:
node.needed = needed or mark_needed_nodes(child, given_nodes)
return node.needed
您可以致电mark_needed_nodes(root, given_nodes)
。
假设given_nodes
是基于散列的字典,复杂性在树中的节点数是线性的。
答案 1 :(得分:1)
我认为,没有必要遍历整棵树。我们可以从每个给定的叶节点“直线”绘制直到根。
这样的事情:
答案 2 :(得分:0)
假设您的查询集中有k个节点,树中有n个节点。如果您需要在同一个树上执行许多查询,并且树比典型的查询集大得多,那么您可以考虑以下解决方案。
您可以先preprocess your tree in linear time so that you can determine the lowest common ancestor of a pair of nodes in constant time。然后,对于给定的查询,您可以找到两个查询节点的最低共同祖先,然后查找该节点的最低共同祖先和查询中的第三个节点等,以确定您的所有节点的最低共同祖先。查询在O(k)时间整体设置。但是,预处理和查询都很复杂,除非您的树与查询大小相比很大,并且在同一个树上有许多单独的查询(因此预处理所花费的时间得到回报),这不太可能是最快的方式。 / p>