我有这段代码,用于计算Least common Ancestor
中给定的两个nodes
的{{1}}。
目前,它假设两个节点都存在。我可以编写一个辅助方法来检查节点是否存在,然后调用Binary tree
方法。这将需要遍历树两次。我想知道当我的当前代码不存在节点时是否有办法检查和处理情况。
LCABT
答案 0 :(得分:2)
让函数返回一对(state, lca)
。 state
必须是以下之一:
0: Neither v1 nor v2 appear at or under root; lca is meaningless.
1: Only v1 appears at or under root; lca is meaningless.
2: Only v2 appears at or under root; lca is meaningless.
3: Both v1 and v2 appear at or under root, and have LCA equal to lca.
该功能应从检查基本情况开始:
LCABT(Node root, int v1, int v2) {
if (root == null) then return (0, null);
否则,递归其左右儿童,看看其中一个是否能自行解决问题:
(s1, lca1) = LCABT(root.left, v1, v2);
(s2, lca2) = LCABT(root.right, v1, v2);
如果s1
或s2
为3,则已找到LCA(分别为lca1
或lca2
)并可立即返回。 (实际上,你甚至可以在第二次调用s1 == 3
之前检查LCABT()
是否获得加速:如果是,那么我们已经拥有了LCA并且不需要第二次调用。)
if (s1 == 3) then return (3, lca1);
if (s2 == 3) then return (3, lca2);
否则,设置s = s1 | s2
(即按位OR)。如果s == 3
我们知道root
是LCA,但我们尚未考虑所有方式,它可以是LCA:它仍然可以是LCA时只有v1
和v2
中的一个出现在其子级或其子级下,前提是另一个值位于root
本身:
s = s1 | s2;
if (root.data == v1) then s = s | 1;
if (root.data == v2) then s = s | 2;
现在所有root
都是LCA的情况都是s == 3
,所以如果s == 3
那么我们可以立即返回(3, root)
:
if (s == 3) then return (3, root);
否则,v1
和v2
中只有一个位于root
或之下,因此我们应该返回一个值,表明它是哪一个:
return (s, null);
}
最后,对LCABT()
的原始顶级调用显然应该仅在函数返回state
值为3时才将该函数视为成功。
此算法相对于您的算法的另一个优点是,它不会被树中v1
或v2
的重复副本所迷惑。