[日常一练]二叉树的最近公共祖先(java)

公共祖先题意:

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

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

 力扣:236. 二叉树的最近公共祖先 - 力扣(LeetCode)

思路:

p或q在根上,根就是公共祖先;

图示:

一个在根左边,一个在根右边;

图示:

两个都在根左边 或者 两个都在根右边;

图示:

要么就是一颗空树;

代码实现:

 public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
      
    }

递归实现: 

 public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
          //1.如果根节点是空,直接是空;
        if(root == null) {
            return null;
        }
        //2.如果p或者q等于root返回root
        if(root.val == q.val || root.val == p.val) {
            return root;
        }
        //3.在左树里面去找q或者p
        TreeNode leftTree = lowestCommonAncestor(root.left,p,q);
        TreeNode rightTree = lowestCommonAncestor(root.right,p,q);
        if(leftTree != null && rightTree != null) {
            return root;
            //两个都在左,返回在左边找到的第一个节点
        } else if (leftTree != null) {
            return leftTree;
            //两个都在右,返回在右边找到的第一个节点
        } else if(rightTree != null) {
            return rightTree;
        }
        return null;
    }

使用栈来实现:

思路:

把到p节点路线节点存到栈当中,q也一样,谁大,让谁多走到栈相同大小,然后再同时出栈,并且判断;

图例:

总结:

1.把p和q的路线节点存进栈内

2.判断即可

代码示例:

 public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        //1.把数据全部放进栈中
        //2.再进行判断
        Stack<TreeNode> stack1 = new Stack<>();
        //把P传入栈中
        getpath(root, p, stack1);
        //把q传入栈中
        Stack<TreeNode> stack2 = new Stack<>();
        getpath(root, q, stack2);
        //此刻的stack1和2已经存放进去p和q路径的数据了
        int x1 = stack1.size();
        int x2 = stack2.size();
        //让栈中元素多的先出,出到栈内大小一致为止
        if (x1 > x2) {
            int a = x1 - x2;
            while (a != 0) {
                stack1.pop();
                a--;
            }
        } else {
            int a = x2 - x1;
            while (a != 0) {
                stack2.pop();
                a--;
            }
        }
        //出栈内的元素也就是栈1和栈2不为空,一直出到元素一致,否则则没有
        while (!stack1.isEmpty() && !stack2.isEmpty()) {
            if (stack1.peek() != stack2.peek()) {
                stack1.pop();
                stack2.pop();
            } else {
                return stack1.pop();
            }
        }
        //如果走到这说明栈为空,且没有q或者p,直接返回null
        return null;
    }
        //创建一个函数专门找p或q的数据并且存放到栈当中去
    public boolean getpath(TreeNode root,TreeNode node,Stack<TreeNode> stack){
        //进来是找P或者Q的数据,并存放到栈当中去,那也就是说,node和root不能为空
        if(root == null || node == null) return false;
         //如果不为空呢?
        stack.push(root);
        if(root == node) return true;
        boolean leftTree = getpath(root.left,node,stack);
        if(leftTree) return true;
        boolean rightTree = getpath(root.right,node,stack);
        if(rightTree) return true;
        stack.pop();
        return false;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Autumn60

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值