代码随想录二叉树——二叉搜索树的最近公共祖先

题目

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]
代码随想录二叉树——二叉搜索树的最近公共祖先_第1张图片
示例 1: 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 输出: 3 解释: 节点 5 和节点 1 的最近公共祖先是节点 3。

示例 2: 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 输出: 5 解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。

说明:

所有节点的值都是唯一的。
p、q 为不同节点且均存在于给定的二叉树中。

思路

最近公共祖先的定义: 设节点 root 为节点 p,q的某公共祖先,若其左子节点 root.left和右子节点 root.right都不是 p,q的公共祖先,则称 root 是 “最近的公共祖先” 。

根据如上定义,最近公共祖先只有三种情况:

(1)pq分别在root的子树中,且分别在root的两侧(分别在左右子树中)
(2)p = rootqroot的左/右子树中
(3 )q = rootproot的左/右子树中

本题给定了两个重要条件:① 树为 二叉搜索树(中序遍历有序) ,② 树的所有节点的值都是 唯一 的。根据以上条件,可方便地判断 p,qroot 的子树关系,即:

(1)若 root.val < p.val,则 proot 右子树 中;
(2)若 root.val > p.val,则 proot 左子树 中;
(3)若 root.val=p.val,则 proot指向 同一节点 。

方法一:迭代

算法流程如下:
代码随想录二叉树——二叉搜索树的最近公共祖先_第2张图片
代码随想录二叉树——二叉搜索树的最近公共祖先_第3张图片
代码随想录二叉树——二叉搜索树的最近公共祖先_第4张图片
代码随想录二叉树——二叉搜索树的最近公共祖先_第5张图片
java代码如下:

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        while(root != null) {
            if(root.val < p.val && root.val < q.val) // p,q 都在 root 的右子树中
                root = root.right; // 遍历至右子节点
            else if(root.val > p.val && root.val > q.val) // p,q 都在 root 的左子树中
                root = root.left; // 遍历至左子节点
            else break;
        }
        return root;
    }
}

方法二:递归

java代码如下:

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root.val < p.val && root.val < q.val)//p,q都在root的右子树
            return lowestCommonAncestor(root.right, p, q);
        if(root.val > p.val && root.val > q.val)//p,q都在root的左子树
            return lowestCommonAncestor(root.left, p, q);
        return root;
    }
}

你可能感兴趣的:(代码随想录,算法,数据结构)