剑指offer-68:节点的公共祖先


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

  • 若当前节点值大于两个节点值,则说明这两个节点在该两个节点左子树中
  • 若当前节点值小于两个节点值,则说明这两个节点在该两个节点右子树中

思路:对于二叉搜索树其后序遍历有序,因此若当前节点的值大于两个节点的值,则说明这两个节点在当前节点的左子树中,若当前节点的值小于两个节点的值,则说明这两个节点在当前节点的右子树中。

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null) {
            return null;
        }
        if (root.val > p.val && root.val > q.val) {
            return lowestCommonAncestor(root.left, p, q);
        }
        if (root.val < p.val && root.val < q.val) {
            return lowestCommonAncestor(root.right, p, q);
        }
        return root;
    }
}

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

  • 求最小公共祖先,需要从底向上遍历,那么二叉树,只能通过后序遍历实现从低向上的遍历方式。
  • 在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。
  • 如果left 和 right都不为空,说明此时root就是最近公共节点。
  • 如果left为空,right不为空,就返回right,说明目标节点是通过right返回的,反之依然
class Solution {
    public 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 root;
        }
        if (left != null && right == null) {
            return left;
        } else if (left == null && right != null) {
            return right;
        } else {
            return null;
        }
    }
}

相关