先根遍历
算法思路
其实所有情况可以分为两类:
- 第一种情况:
p和q中的一个,是另一个的根节点之一,比如下面第三张图中,5是4的根节点。或者第一张图中,7和它的子树无数层下的某个节点。 - 第二种情况:谁也不是谁的根节点。
以下代码是核心:
if (left == null) {
return right;
}
if (right == null) {
return left;
}
return root;
- 如果遇到
p或者q,我们应该把他们往上传递。 - 遇到其他非目标元素,从叶子节点开始往上传递
null,直到遇到p或者q的父节点,将null换成p或者q往上传递。
最终情况:
- 上述第二种情况,两条路径往上传递,两者汇合,
return root。 - 第一种情况,遇到
p或者q就停止往下递归了,将最先遇到的往上传递。
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q) {
return root;
}
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if (left == null) {
return right;
}
if (right == null) {
return left;
}
return root;
}