剑指offer68-II二叉树的最近公共节点

前言

此树非二叉排序树,无法利用有序条件。
不能在递归过程中做事情,在回溯时来判断p、q是否来自左右节点。遇到p、q就返回其节点,然后在右子树找是否有另一个节点,存在情况如下。
1)左右都找到相应节点,则返回root。
2)都在左,从上到下找到一个节点,就返回左边较上的节点作为公共节点。
3)都在右,从上到下找到一个节点,就返回右边较上的节点作为公共节点。

一、回溯

//剑指offer68—II二叉树的最近公共祖先
    public TreeNode lowestCommonAncestor3(TreeNode root, TreeNode p, TreeNode q) {
        //返回p或者q节点,利用回溯的过程进行判断,p,q在数的左端还是右端,如果是左端,返回左;右端返回右;左右返回root
        if(root == null)
            return null;
        if(root == p || root == q)
            return root;
        TreeNode left = lowestCommonAncestor3(root.left,p,q);
        TreeNode right = lowestCommonAncestor3(root.right,p,q);
        if(left != null && right != null){
            return root;
        }
        if(left != null)
            return left;
        if(right != null)
            return right;
        return null;
    }

二、回溯+剪枝

当出现第一种情况,左右节点都寻找到相应的p、q时,则再次递归下去就直接遇到出口,从而进行剪枝。

1、剪枝

//剑指offer68—II二叉树的最近公共祖先+剪枝
    boolean isFind = false;
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        //返回p或者q节点,利用回溯的过程进行判断,p,q在数的左端还是右端,如果是左端,返回左;右端返回右;左右返回root
        if(root == null)
            return null;
        if(root == p || root == q)
            return root;
            //设置标识,进行剪枝(提前return null)
        if(isFind)
            return null;
        TreeNode left = lowestCommonAncestor(root.left,p,q);
        TreeNode right = lowestCommonAncestor(root.right,p,q);
        if(left != null && right != null){
        //一旦寻找到真正的最近公共祖先,就设置已找到条件,为剪枝做准备。
            isFind = true;
            return root;
        }
        if(left != null)
            return left;
        if(right != null)
            return right;
        return null;
    }

总结

1)掌握四种遍历方式
2)利用好回溯
3)可以提前返回就不需要进行无意义的递归,需剪枝。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值