给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]
说明:
- 所有节点的值都是唯一的。
- p、q 为不同节点且均存在于给定的二叉树中。
题目来源:https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
// 如果root是null,则说明我们已经找到最底了,返回null表示没找到
if(root == NULL){//
return NULL;
}
//遍历root 找到了与p或q相等的节点
//由于是从根节点出发,由上至下的寻找,所以找到的p或q一定是深度较大的那个,即可作为祖先节点
if( root == p || root == q ) {
return root;
}
//节点不相等,则分别遍历左节点、右节点
TreeNode* left = lowestCommonAncestor(root->left, p, q);
TreeNode* right = lowestCommonAncestor(root->right, p, q);
//如果左边没找到与p、q相等的点,证明p、q同在root 的右测
//那么最终的公共祖先就是右子树找到的结点
if(left == NULL) {
return right;
}
//如果右边没找到与p、q相等的点,证明p、q同在root的左边,
//那么最终的公共祖先是左子树找到的节点
if (right == NULL){
return left;
}
//左右子树都不为空,那么说明p、q两节点一个在root的左边(左子树),一个在root 右边(右子树)
//那么root就是它们的祖先
return root;
}
};
复杂度分析:
时间复杂度 O(N) : 其中 N为二叉树节点数;最差情况下,需要递归遍历树的所有节点。
空间复杂度 O(N) : 最差情况下,递归深度达到 N ,系统使用 O(N) 大小的额外空间。