【Leetcode】236. Lowest Common Ancestor of a Binary Tree

题目地址:

https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/

寻找一棵二叉树某两个节点ppp和qqq的最近公共祖先。

先证:www是ppp与qqq的最近公共祖先,当且仅当w=pw=pw=p且qqq是ppp的后代(或者反之),或者ppp与qqq分别在www的左右子树之中。

先证充分性:若ppp与qqq分别位于www的左右子树中,那么很显然www是公共祖先,并且www的左右子树根都不是公共祖先,这说明了www的“最近”性质。证毕。

再证必要性:反证法。不妨设ppp与qqq都位于www的左子树中,那么www的左子树根是更近的公共祖先,与www的“最近”性质矛盾。证毕。

所以只需要找到一个ppp和qqq分别位于它左右子树的那个节点就行了。为此我们需要在root的左右两个子树中搜索ppp和qqq,如果一边搜索出ppp另一边搜索出qqq返回即可。代码如下:

public 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;
        } else if (left == null) {
            return right;
        } else {
            return left;
        }
    }
}

class TreeNode {
    int val;
    TreeNode left, right;
    TreeNode(int x) {
        val = x;
    }
}

时间复杂度O(n)O(n)O(n),空间O(h)O(h)O(h)。

算法正确性证明:

需要证明这个函数,若以root为树根的树中存在ppp与qqq,则会返回其最近公共祖先,若只存在ppp或qqq,则对应地返回ppp或qqq,否则会返回null。
如果root是ppp或者qqq显然正确。如果树的节点数为000,111,222或333时显然正确;假设树的节点数是kkk的时候也正确,如果树的节点数是k+1k+1k+1,那么其左右子树节点数必然小于等于kkk,据数学归纳法,若left与right里分别有ppp和qqq,那说明ppp和qqq在root的两端,那就返回root。否则按照数学归纳法,就返回了正确答案。证毕。

【Leetcode】236. Lowest Common Ancestor of a Binary Tree【Leetcode】236. Lowest Common Ancestor of a Binary Tree edWard的算法世界 发布了140 篇原创文章 · 获赞 0 · 访问量 7773 私信 关注
上一篇:2020.2.25普及C组 跳棋(jump) 【纪中】【DP】【单调队列优化】


下一篇:numpy实现NMS