摘要
剑指 Offer 68 - I. 二叉搜索树的最近公共祖先
剑指 Offer 68 - II. 二叉树的最近公共祖先
一、二叉搜索树的最近公共祖先
注意到题目中给出的是一棵二叉搜索树,因此我们可以快速地找出树中的某个节点以及从根节点到该节点的路径,例如我们需要找到节点 p:
- 我们从根节点开始遍历;
- 如果当前节点就是p,那么成功地找到了节点;
- 如果当前节点的值大于p的值,说明p应该在当前节点的左子树,因此将当前节点移动到它的左子节点;
- 如果当前节点的值小于p的值,说明p应该在当前节点的右子树,因此将当前节点移动到它的右子节点。
package Tree;
/**
* @Classname JZ68二叉搜索树的最近公共祖先II
* @Description TODO
* @Date 2023/2/23 21:45
* @Created by xjl
*/
public class JZ68二叉搜索树的最近公共祖先II {
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
int value=root.val;
if (p.val<value && q.val<value){
return lowestCommonAncestor(root.left,p,q);
}
if (p.val>value&&q.val>value){
return lowestCommonAncestor(root.right,p,q);
}
if (root==q||root==q){
return root;
}
return root;
}
}
二、二叉树的最近公共祖先
祖先的定义: 若节点p在节点 root的左(右)子树中,或p=root ,则称 root是p的祖先。
最近公共祖先的定义:设节点root为节点p,q的某公共祖先,若其左子节点 root.left和右子节点 root.right都不是p,q的公共祖先,则称root是 “最近的公共祖先” 。
根据以上定义,若 rootroot 是 p,q的 最近公共祖先 ,则只可能为以下情况之一:
- p 和q在root的子树中,且分列root的异侧(即分别在左、右子树中);那p、q的公共祖先就是root。
- p=root,且q在root 的左或右子树中;
- q=root ,且p 在root 的左或右子树中;
考虑通过递归对二叉树进行先序遍历,当遇到节点p或q时返回。从底至顶回溯,当节点p,q在节点 root的异侧时,节点root即为最近公共祖先,则向上返回root 。
递归解析:
终止条件:
- 当root节点为null,则直接返回 null;
- 当root等于p,q,则直接返回root;
递推工作:
- 开启递归左子节点,返回值记为 left;
- 开启递归右子节点,返回值记为 right;
返回值: 根据left和right,可展开为四种情况;
- 当left和right同时为空 :说明root的左 / 右子树中都不包含p,q,返回null;
- 当left和right同时不为空 :说明p,q分列在root的异侧 (分别在 左 / 右子树),因此 root为最近公共祖先,返回root;
- 当 left为空,right不为空:p,q都不在root的左子树中,直接返回right 。具体可分为两种情况:
- p,q其中一个在root的右子树中,此时right指向P(假设为p);
- p,q两节点都在root的右子树中,此时right指向最近公共祖先节点 ;
package Tree;
/**
* @Classname JZ68二叉树的最近公共祖先
* @Description TODO
* @Date 2023/2/23 17:58
* @Created by xjl
*/
public class JZ68二叉树的最近公共祖先 {
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
/**
* @description 二叉树的最近公共祖先
* @param: root
* @param: p
* @param: q
* @date: 2023/2/23 17:58
* @return: Tree.JZ68二叉树的最近公共祖先.TreeNode
* @author: xjl
*/
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;
}
}
博文参考
《leetcode》