寻找二叉树的最近公共祖先

寻找二叉树的最近公共祖先

这道题在面试过程遇到了两次了,感觉是一个高频考点,特此总结一下

解题思路:

祖先定义: 若节点p 在节点root 的左子树或者右子树中,则称root是p的祖先

最近公共祖先的定义: 设节点root 为节点p,q的最近公共祖先,若其左子节点root.left,和右子节点

root.right 都不是p,q的公共祖先在,则称root 是最近的公共祖先

根据以上定义,若root是p,q的最近公共祖先,则只可能为以下情况之一:

1,p和q在root的子树中,且分列root的两侧,即分别为左右子树中。

2, p = root ,且q 在root 的左或右子树中

3,q = root,且 p 在root 的左或者右子树中

考虑通过递归对二叉树进行后续遍历,当遇到节点p 或者q 时返回,从底至顶回溯,当节点p ,q,在节点root两侧时,即为最近公共祖先,则向上返回root

递归解析

1,终止条件:

1,当越过叶子节点,则直接返回Null

2,当root 等于p ,q,则直接返回root

2.递推工作

1,开启递归左子节点,返回值记为left

2, 开启递归右子节点,返回值记为right

3, 返回值

1,当left 和right 同时为空,说明,root 的左/右子树中都不包含p,q. 返回Null

2, 当left 和right 同时不为空,说明,p,q,分别在root的两侧,因此root为最近的公共祖先,返回root

3, 当left 为空,right 不为空: p,q 都不在root 的左子树中,直接返回right,具体可分为两种情况:

  1. p,q, 其中一个在root 的右子树中,p 或者q 就是root 的右子树, 此时right 指向 p(假设为p )

  2. p,q,两个基点都在root的右子树中,此时的right 指向最近的公共祖先节点

4,当left 不为空,right 为空,直接返回left ,与3 同理


public static TreeNode lowestCommonAncestor (TreeNode root ,TreeNode p,TreeNoe 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 &&right === null ){return null;}

   if(left == null ){return right; }
   if(right == null ){return left; }
   return root;
}

验证:


import java.util.*;

public class TreeExercise1 {

   public static void main(String[] args ){
       TreeNode p3 =  new TreeNode(3);
       TreeNode p5 =  new TreeNode(5);
       TreeNode p1 =  new TreeNode(1);
       TreeNode p6 =  new TreeNode(6);
       TreeNode p2 =  new TreeNode(2);
       TreeNode p0 =  new TreeNode(0);
       TreeNode p8 =  new TreeNode(8);
       TreeNode p7 =  new TreeNode(7);
       TreeNode p4 =  new TreeNode(4);

       p3.left =  p5;
       p3.right = p1;
       p5.left =  p6;
       p5.right = p2;
       p1.left = p0;
       p1.right = p8;
       p2.left = p7;
       p2.right = p4;

//       inorferFix(p3);

       TreeNode res =  lowestCommonAncestor(p3,p2,p6);
       inorderFix(res);



  }
   public static 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 && right == null ){ return null; }
       if(left == null ){return right; }
       if(right == null ){return left ; }
       return root;
  }
   
   private  static void  inorferFix(TreeNode  root ){
       if(root==null ){
           return;
      }
       if(root.left != null ){
           inorferFix(root.left);
      }
       System.out.println(root.val);
       if(root.right != null ){
           inorderFix(root.right);
      }
  }
}
https://www.nowcoder.com/ta/exam-qq



posted @ 2020-08-09 15:10  同济小孙  阅读(677)  评论(0编辑  收藏  举报