Основная идея маркировки наличия ряда в ветви дерева является использование непустого указателя для числа НАЙДЕН и нулевого указателя для NOTFOUND.
В стек вызовов ветры назад, как только число (p
или q
) найдено, или когда root
является null
. Позже дается четкое указание на отсутствие искомого номера.
Есть четыре возможных сценария:
1.) И под одним родителем.
root
/\
Leftsubtree Rightsubtree
p/q q/p
В этом случае, в коде ниже, момент наступит, когда это выполнено if(left != null && right != null) return root;
2.) Один родитель другого.
q/p p/q
/ OR \
Leftsubtree Rightsubtree
p/q q/p
В этом случае, это будет выполнено, if(root == null || root == p || root == q) return root;
3.) В любом из них нет в дереве. Это условие будет идти не обнаружено. Как показано в случае № 2, функция возвращается немедленно без дальнейшего перемещения и ищет свою копию в дереве ниже.
4.) Ни один из них не присутствует в дереве.
Первая строка if(root == null ... return ;
будет выполнена для каждого несуществующего ребенка. Конечным результатом будет null
return, так как ни один из них не будет найден.
По строковой линии пояснения.
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null || root == p || root == q) return root;
/* (root == null) This proves that root is not in the branch of tree of our interest. Returning null would means NOTFOUND.*/
/* (root == p || root == q) either p or q or both are found. Returning non-null root would means FOUND. */
/*Check for presence in leftsubtree */
TreeNode left = lowestCommonAncestor(root.left, p, q);
/*Check for presence in rightsubtree */
TreeNode right = lowestCommonAncestor(root.right, p, q);
/* root
/\
leftsubtree Rightsubtree
p/q q/p
*/
if(left != null && right != null) return root; //both the numbers are found inside tree under root
// left or right subtree OR both don't have p or q. Return the overall find result under root.
return left != null ? left : right;
}
Рекурсивные функции могут быть очень сложными для понимания. Рисование их на бумаге помогает. –
Код здесь немного более компактный вариант того, что в этом ответе: http://stackoverflow.com/a/9046307/2513200 – Hulk
@Hulk без обид, разница совершенно не имеет значения, даже для перспективы компилятора. –