牛客 剑指offer:最近公共祖先

8 篇文章 0 订阅
7 篇文章 0 订阅

题目:最近公共祖先

思路1:

在某个节点小找是否包含某个子节点很容易,所以我们可以对所有节点,判断是否包含给定的两个节点,取最近的即可。这个方法可以AC,但其实,两个递归做了很多重复的运算。

思路2:

其实,祖先节点只有如下三种情况

  1. 两个节点分别在祖先节点两侧;
  2. a节点就是他们的祖先,b节点在a的左子树或右子树;
  3. b节点就是他们的祖先,a节点在b的左子树或右子树;

我们从头深搜二叉树,

  • 如果root节点为空, 或者当前root节点等于两个节点其中一个,就返回当前节点root
  • 递归对root左子树、root右子树分别查找:
    如果左右子树返回的结果都不为空,说明左右子树分别找到了两个节点,此时,root即为所求,返回即可;(情况1)
    否则,返回左右子树的返回结果不为空的节点。(情况2或3)

代码1:

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param root TreeNode类 
     * @param o1 int整型 
     * @param o2 int整型 
     * @return int整型
     */
    public int res;
    public int lowestCommonAncestor (TreeNode root, int o1, int o2) {
        // write code here
        search(root, o1, o2);
        return res;
    }
    public void search (TreeNode root, int o1, int o2) {
        if (root == null) {
            return;
        }
        if (contains(root, o1) && contains(root, o2)) {
            res = root.val;
        }
        search(root.left, o1, o2);
        search(root.right, o1, o2);
    }
    public boolean contains (TreeNode root, int num) {
        if (root == null) {
            return false;
        }
        if (root.val == num) {
            return true;
        }
        return contains(root.left, num) || contains(root.right, num);
    }
}

代码2:

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param root TreeNode类 
     * @param o1 int整型 
     * @param o2 int整型 
     * @return int整型
     */
    public int lowestCommonAncestor (TreeNode root, int o1, int o2) {
        // write code here
        return search(root, o1, o2).val;
    }
    public TreeNode search (TreeNode root, int o1, int o2) {
        if (root == null || root.val == o1 || root.val == o2) {
            return root;
        }
        TreeNode left = search(root.left, o1, o2);
        TreeNode right = search(root.right, o1, o2);
        if (left != null && right != null) {
            return root;
        }
        return left == null? right: left;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值