题目
算法思路
与【JZ-68-I】的区别在于二叉树不再是二叉搜索树了,也就是说我们无法利用节点的值的大小关系来判断节点的位置关系了,可以采用 深度优先遍历。
递归终止条件:
- 越过了叶节点:直接返回 n u l l null null
- r o o t root root 等于p、q:返回 r o o t root root
递推过程:
- 开启左子节点的递归,返回值记为 l e f t left left
- 开启右子节点的递归,返回值记为 r i g h t right right
返回值(情况1.可以合并到3.和4.内):
- l e f t left left、 r i g h t right right 均为空:返回 n u l l null null;
- l e f t left left、 r i g h t right right 均不为空:说明p、q分别在 r o o t root root 的左右子树中, r o o t root root 就是最近的公共祖先,返回 r o o t root root;
- l e f t left left 为空, r i g h t right right 不为空:说明p、q都不在 r o o t root root 的左子树中(可能是均在右子树中,也有可能是其中一个在右子树中),返回 r i g h t right right(此时的 r i g h t right right可能指向最近公共祖先,也有可能指向在右子树中的那一个节点);
- l e f t left left 不为空, r i g h t right right 为空:与 3. 同理
具体代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
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)return right;
if(right == null)return left;
return root;
}
}
复杂度分析
- 时间复杂度: O ( n ) O(n) O(n), n 为二叉树节点总数。最差情况下,需要遍历树的所有节点。
- 空间复杂度: O ( n ) O(n) O(n),递归深度最大为 n