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

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

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

示例 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 。因为根据定义最近公共祖先节点可以为节点本身。
示例 3:

输入:root = [1,2], p = 1, q = 2
输出:1

提示:

树中节点数目在范围 [2, 105] 内。
-109 <= Node.val <= 109
所有 Node.val 互不相同 。
p != q
p 和 q 均存在于给定的二叉树中。

来源:力扣(LeetCode)
链接:OJ链接

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
     if(root==null){
          return null;
      } 
     if(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 root;
     }else if(lefT!=null){
         return lefT;
     }else{
         return righT;
     }
  }
}
class Solution {  
    //root 根节点  node指定节点  stack存放从根节点到指定节点的路径
    public boolean getPath(TreeNode root,TreeNode node,Stack<TreeNode> stack){
        if(root==null||node==null)  return false;
         stack.push(root);
        if(root==node)   return true;  
        boolean flag=getPath(root.left,node,stack);
        if(flag==true){
            return true;
        }
        flag=getPath(root.right,node,stack);
        if(flag==true)  return true;
        stack.pop();
        return false;
    }
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q){
        if (root==null)    return null;
        Stack<TreeNode> stack1=new Stack<>();
        getPath(root,p,stack1);
        Stack<TreeNode> stack2=new Stack<>();
        getPath(root,q,stack2);

        int size1=stack1.size();
        int size2=stack2.size();
        if(size1>size2){
            int size=size1-size2;
           while(size!=0){
               //出第一个栈里面的元素
               stack1.pop();
               size--;
           }
           while(!stack1.isEmpty()&&!stack2.isEmpty()){
               //判断地址
               if(stack1.peek()==stack2.peek()){
                   return stack1.pop();
                }else{
                   stack1.pop();
                   stack2.pop();
                }
           }
        }else{
             int size=size2-size1;
             while(size!=0){
               //出第一个栈里面的元素
               stack2.pop();
               size--;
           }
           while(!stack1.isEmpty()&&!stack2.isEmpty()){
               //判断地址
               if(stack1.peek()==stack2.peek()){
                   return stack1.pop();
               }else{
                   stack1.pop();
                   stack2.pop();
               }
           }
        }
        return null;
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值