LeetCode--236. 二叉树的最近公共祖先

难度中等题。

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

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

思路有多种。

        1. 纯粹的自底向上。后序遍历中,先找到该节点,那么返回一个true。当某个节点的左右子树都返回true时,该节点就是要求的。如果两个点是祖先后代关系,那么返回为当前节点值等于其中一个查询值且一个子树为true时,那么该节点也是要找的。

        2. 自底向上和自顶向下结合的。首先在递归遍历中从根节点出发自顶向下找到第一个值的位置,然后暂定该点为要求的。接着找其子树是否存在第二个点,如果存在,那么返回刚刚暂定的结果。如果不存在,那么就会在回溯过程中回溯到该点(用暂定结果点等于当前遍历值表示回溯到暂定结果了,该子树下没有第二个,那么下一步回溯就要吧暂定结果向上取,继续这个过程)。

        3. 用一个HashMap<当前点,父节点>,放进去这个树,根据两个给定值在HashMap中找父节点序列,第一个共同都是父节点的就是要求的。

    我的代码是第二种。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

    public TreeNode res;//就是暂存结果的
    public boolean isRoot = true;//用于标记是否还在遍历当前暂定结果的子树找第二个点
    public boolean success = false;//找到了
    public void find(TreeNode root, int p,int q){
        if(root == null || success)
            return;
        if ((root.val == p || root.val == q) && res == null){//找到了第一个点
            res = new TreeNode(root.val);
        }
        find(root.left,p,q);
        if(success)
            return;
        if(!isRoot){//设定暂时结果点
            res = root;
            isRoot = true;
        }
        find(root.right,p,q);
        if(success)
            return;
        if((root.val == p || root.val == q) && res.val != root.val){//找到第二个点
            success = true;
            return;
        }
        if(res != null){//标记该树遍历完了还是没有找到第二个
            if(res.val == root.val && isRoot){
                isRoot = false;
            }
        }
    }

猜你喜欢

转载自blog.csdn.net/lfanchenyu/article/details/106038990