原题说明
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”
_______3______
/ \
___5__ ___1__
/ \ / \
6 _2 0 8
/ \
7 4
For example, the lowest common ancestor (LCA) of nodes 5
and 1
is 3
. Another example is LCA of nodes 5
and 4
is 5
, since a node can be a descendant of itself according to the LCA definition.
解题思路
本题要求找出两个节点的最近的共同祖先。
一个简单的思路是我们可以遍历整棵树,然后用一个map
记录每个节点的父节点。这样可以找出节点p
和q
到根节点的path
,然后就能方便的找出最近的共同祖先。但是这样要求我们用额外的map
来记录每个节点的信息,空间复杂度为O(n)。
换一个思路,我们发现:假设对于一个节点,如果它的右子树里只找到了其中一个目标节点,而在它的左子树中没有找到另一个目标节点;或者它的左子树里只有一个目标节点,而它的右子树里没有另外一个目标界节点,那么当前节点就不是两个目标节点的最近公共祖先了。除此之外的情况,当前节点就是两个目标节点的公共祖先了。 我们可以从叶子节点向上,标记子树中出现目标节点的情况。若一个节点的左右子树都有标记,则当前节点就是共同祖先。
我们用递归的方法实现代码,会非常简洁。
示例代码 (python)
1 | # Definition for a binary tree node. |
示例代码 (cpp)
1 | /** |
复杂度分析
最坏情况每个节点visit一次,因此时间复杂度为O(n)
。
时间复杂度: O(n)
空间复杂度: O(1)
归纳总结
思考清楚共同祖先的定义,我们用递归的方法实现代码。同时我们可以看出,这题本质上还是对 Tree 遍历的变种。
好了,这几天就和大家讨论到这里,种香蕉树去了。