在 n-array 树中生成所有叶子到叶子的路径

问题描述

给定一棵 N 元树,我必须在 n 数组树中生成所有叶子到叶子的路径。路径也应该表示方向。举个例子:

树:

               1
            /     \
          2        6
        /   \
       3     4
      /
     5  

路径:

  • 5 上 3 上 2 下 4
  • 4 上 2 上 1 下 6
  • 5 上 3 上 2 上 1 下 6

这些路径可以按任意顺序排列,但需要生成所有路径。

我有点看到这种模式:

  • 看起来我必须按顺序遍历和
  • 需要保存我目前看到的内容

然而,无法真正想出一个实际的工作算法。

谁能告诉我正确的算法?

我不是在寻找实际的实现,只是伪代码和概念性的想法将不胜感激。

解决方法

我要做的第一件事是执行有序遍历。因此,我们将按照从最左侧到最右侧节点的顺序累积所有叶子。(在您的情况下,这将是 [5,4,6]) 在此过程中,我肯定会找到节点与其父节点之间的映射,以便我们稍后执行 dfs。我们可以将这个映射保留在 HashMap(或其类似物)中。除此之外,我们还需要有节点与其优先级之间的映射,我们可以从有序遍历的结果中计算出它。在您的示例中,顺序为 [5,3,2,1,6],优先级列表分别为 [0,5]

这里我假设我们的节点看起来像(我们可能没有映射节点 -> 先验的父节点):

class TreeNode {
    int val;
    TreeNode[] nodes;

    TreeNode(int x) {
        val = x;
    }
}

如果我们有 n 个叶子,那么我们需要找到 n * (n - 1) / 2 个路径。显然,如果我们设法找到从叶子 A 到叶子 B 的路径,那么我们可以轻松计算从 BA 的路径。 (通过转换 UP -> DOWN 反之亦然)

然后我们开始遍历我们之前计算的叶子数组。对于数组中的每个叶子,我们应该寻找位于当前叶子右侧的叶子的路径。 (因为我们已经找到了从最左边的节点到当前叶子的路径)

为了执行 dfs 搜索,我们应该向上走,并为每个遇到的节点检查我们是否可以找到它的子节点。我们不应该去一个优先级低于当前叶子优先级的孩子。 (这样做会引导我们到我们已有的路径)除此之外,我们不应该访问我们沿途已经访问过的节点。

当我们从某个节点执行 dfs 时,我们可以维护某种结构来保留我们迄今为止遇到的节点(例如,StringBuilder,如果您使用 Java 编程)。在我们的例子中,如果我们从叶子 5 到达叶子 4,我们累积路径 = 5 UP 3 UP 2 DOWN 4。由于我们已经到达了一个叶子节点,我们可以丢弃最后访问的节点并继续进行 dfs 和路径 = 5 UP 3 UP 2

可能有更先进的技术来解决这个问题,但我认为这是一个很好的起点。我希望这种方法能帮到你。

,

如果没有用 Python 编程,我就无法创建解决方案。假设我没有忽略一个角落案例,我的尝试是这样的:

在深度优先搜索中,每个节点都接收下行路径,如果节点是叶节点,则发出它们(加上自身)或将下行路径传递给其子节点 - 唯一需要考虑的是叶节点是上行路径的起点,因此这些是从左到右子节点的输入以及返回到父节点。

def print_leaf2leaf(root,path_down):
    for st in path_down:
        st.append(root)
    if all([x is None for x in root.children]):
        for st in path_down:
            for n in st: print(n.d,end=" ")
            print()
        path_up = [[root]]
    else:
        path_up = []
        for child in root.children:
            path_up += child is not None and [st+[root] for st in print_root2root(child,path_down + path_up)] or []
    for st in path_down:
        st.pop()
    return path_up

class node:
    def __init__(self,d,*children):
        self.d = d
        self.children = children
    
##               1
##            /     \
##          2         6
##        /   \      /
##       3     4     7
##      /          / | \
##     5          8  9  10
five = node(5)
three = node(3,five)
four = node(4)
two = node(2,three,four)
eight = node(8)
nine = node(9)
ten = node(10)
seven = node(7,eight,nine,ten)
six = node(6,None,seven)
one = node(1,two,six)

print_leaf2leaf(one,[])