Это из проблемы 4.8 из Cracking the Coding Interview 6th edition. Следующий код является одним из решений следующего приглашения: «Найти первого общего предка двух узлов в двоичном дереве»
TreeNode commonAncestor(TreeNode root, TreeNode p, TreeNode q){
/* Checks if either node is not in the tree, or if one covers the other. */
if(!covers(root, p) || !covers(root, q)){
return null;
} else if (covers(p,q)){
return p;
} else if (cover(q,p)){
return q;
}
/* Traverse upwards until you find a node that covers q. */
TreeNode sibling = getSibling(p);
TreeNode parent = p.parent;
while(!covers(sibling, q)){
sibling = getSibling(parent);
parent = parent.parent;
}
return parent;
}
boolean covers(TreeNode root, TreeNode p){
if(node == null) return false;
if(root == p) return true;
return covers(root.left, p) || covers(root.right,p);
}
TreeNode getSibling(TreeNode node){
if(node == null || node.parent ==null){
return null;
}
TreeNode parent = node.parent;
return parent.left == node ? parent.right: parent.left;
}
В книге говорится, что "этот алгоритм занимает время O (t), где t - это размер поддерева для первого общего предка. В худшем случае это будет O (n)"
Однако, это не вызовы обложек от root в начале commonAncestor, делающие время выполнения O (d + t), где d - это глубина либо p, либо q, в зависимости от того, какой из них глубже.