JZ86 在二叉树中找到两个节点的最近公共祖先
(中等)
题目
描述
示例
输入:
[3,5,1,6,2,0,8,#,#,7,4],5,1
返回值:
3
思路
可用递归的思想,我们可以再写一个返回值和参数都为树结点类型的函数进行递归,让它最终返回待求o1、o2最近的祖先结点,在递归函数中,对左右子树都再次进行递归,若当前结点为空时我们肯定要终止并返回 null,因为此条递归线路并没有找到值为 o1 或 o2 的结点,而如果当前结点值等于给定的 o1 或 o2 时,我们也应该返回此结点,从而结束此条递归线路,因为此条递归线路中含有 o1 或 o2 参数值对应的结点,因为我们之前的递归是对根结点以及其下结点都进行了左右递归,因此我们最终会得到左右子树两边递归的结果返回情况,如果一边为空的话,那么待求公共祖先肯定在另一边,也就是返回另一边的递归结果即可,这个思想需要意会,文字不容易表述,而如果左边右边递归结果结点都不为空,那么说明 o1 或 o2 对应左右子树中的某个结点,那么我们返回当前结点即可,也就是 o1 或 o2 和当前结点构成的树的根结点。
实现
/**
* 递归解法
*
* @param root
* @param o1
* @param o2
* @return
*/
int o1 = 0;
int o2 = 0;
public int lowestCommonAncestor1(TreeNode root, int o1, int o2) {
this.o1 = o1;
this.o2 = o2;
return search(root).val;
}
public TreeNode search(TreeNode node) {
if (node == null || node.val == o1 || node.val == o2) return node;
TreeNode leftNode = search(node.left);
TreeNode rightNode = search(node.right);
if (leftNode == null) return rightNode;
if (rightNode == null) return leftNode;
return node;
}
JZ68 二叉搜索树的最近公共祖先
(中等)
题目
描述
示例1
输入:
{7,1,12,0,4,11,14,#,#,3,5},1,12
返回值:
7
说明:
节点1 和 节点12的最近公共祖先是7
示例2
输入:
{7,1,12,0,4,11,14,#,#,3,5},12,11
返回值:
12
说明:
因为一个节点也可以是它自己的祖先.所以输出12
思路
也可以用递归的思想,代码大体上和上述普通二叉树结构下的代码相似,由于本题是二叉搜索树,由于其结点值“左小右大”的特点,我们不必再根据左右子树递归线路的结果返回情况来判断待求公共祖先,而是可以之间在递归过程中判断是否 o1、o2 的值都小于当前结点值,那么自然就在左树,如果都大于,那么自然在右树,而一个大于一个小于,那么自然待求结点就是递归过程中的当前结点了。
实现
int o1 = 0;
int o2 = 0;
public int lowestCommonAncestor(TreeNode root, int p, int q) {
o1 = p;
o2 = q;
return search(root).val;
}
public TreeNode search(TreeNode node) {
if (node == null || node.val == o1 || node.val == o2) return node;
if (o1 < node.val && o2 < node.val) return search(node.left);
if (o1 > node.val && o2 > node.val) return search(node.right);
return node;
}