有没有办法不使用额外的空间来找到nary树的LCA。 我使用字符串保存了两个节点的预订并找到了公共前缀
答案 0 :(得分:4)
如果节点“知道”它们的深度 - 或者您愿意允许空间计算节点的深度,则可以从较低节点备份到较高节点的相同深度,然后上升一个节点直到他们见面为止。
取决于“额外空间”在这种情况下的含义。你可以用一个整数来做 - 两个节点的深度差异。这太宽了吗?
另一种可能性是你没有父指针,你可以使用指针反转 - 每次遍历指针时,记住你来自的位置,记住下一次遍历的指针,然后就在下一个指针遍历,用后指针替换该指针。当你上树恢复它时你必须扭转它。这将一个指针的空间作为临时空间。另一个整数来保持深度,因为你的工作向下和向上。对于您寻找的两个节点同步执行此操作,以便您可以从较低的节点返回,直到在两次遍历中处于相同的高度,然后从两者中重新开始工作,直到您处于公共节点。这需要三个额外的内存 - 一个用于每个当前深度,一个用于在指针反转期间使用的临时内存。非常节省空间。值得吗?
答案 1 :(得分:2)
返回并为二叉树执行此操作。如果您可以为二叉树执行此操作,则可以为n-ary树执行此操作。
这是a link to LCA in a binary tree:
以下是将其转换为n-ary树LCA后的样子:
public class LCA {
public static <V> Node<V>
lowestCommonAncestor(Node<V> argRoot, Node<V> a, Node<V> b) {
if (argRoot == null) {
return null;
}
if (argRoot.equals(a) || argRoot.equals(b)) {
// if at least one matched, no need to continue
// this is the LCA for this root
return argRoot;
}
Iterator<Node<V>> it = argRoot.childIterator();
// nr of branches that a or b are on,
// could be max 2 (considering unique nodes)
int i = 0;
Node<V> lastFoundLCA = null;
while (it.hasNext()) {
Node<V> node = lowestCommonAncestor(it.next(), a, b);
if (node != null) {
lastFoundLCA = node;
i++ ;
}
if (i >= 2) {
return argRoot;
}
}
return lastFoundLCA;
}
}
答案 2 :(得分:0)
同步遍历两个节点。
C中的伪代码:
struct node {
struct node *offspring[1234];
int payload;
};
/* compare function returning the slot in which this should be found/placed */
int find_index (struct node *par, struct node *this);
struct node *lca(struct node *root, struct node *one, struct node *two)
{
struct node *lca;
int idx1,idx2;
for (lca=root; lca; lca=lca->offspring[idx1] ) {
idx1 = find_index(lca, one);
idx2 = find_index(lca, two);
if (idx1 != idx2 || idx1 < 0) break;
if (lca->offspring[idx1] == NULL) break;
}
return lca;
}