版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zy2317878/article/details/82502431
Description
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 p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”
Given the following binary tree: root = [3,5,1,6,2,0,8,null,null,7,4]
_______3______
/ \
___5__ ___1__
/ \ / \
6 _2 0 8
/ \
7 4
Example 1
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of of nodes 5 and 1 is 3.
Example 2
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
Output: 5
Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself
according to the LCA definition.
Note
- All of the nodes’ values will be unique.
- p and q are different and both values will exist in the binary tree.
Solution 1(C++)
Class Solution{
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q){
if(root == nullptr || root == p || root == q) return root;
TreeNode* left = lowestCommonAncestor(root->left, p, q);
TreeNode* right = lowestCommonAncestor(root->right, p, q);
if(left != nullptr && right !- nullptr) return root;
return left == nullptr ? right : left;
}
};
Solution 2(C++)
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (!root || p == root || q == root) return root;
TreeNode *left = lowestCommonAncestor(root->left, p, q);
if (left && left != p && left != q) return left;
TreeNode *right = lowestCommonAncestor(root->right, p , q);
if (right && right != p && right != q) return right;
if (left && right) return root;
return left ? left : right;
}
};
算法分析
解法一
用递归的方法分析,函数lowestCommonAncestor()返回,以root为根的树中,p与q的最小公共父节点。
- 如果root为空,自然直接返回root;
- 如果q或p等于root,那么直接返回root,说明q或p就是根节点;
- 分别对root->left与root->right两个子节点进行递归调用,返回的节点设为left与right。如果left为空,说明,q与p都在root的右子树中,如果right为空,说明,q与p都在root的左子树中。那么以上两种情况,直接返回left与right中不为空的那一个即可;
- 如果left与right均不为空,那么说明root的q与p分别分布在root的左子树与右子树中。那么root就是根节点。返回root。
解法二
解法二为解法一的优化,主要要注意一点:
当p和q同时为于左子树或右子树中,而且返回的结点并不是p或q,那么就是p和q的最小父结点
所以可以不用再对右结点调用递归函数了,同样,对返回的right也做同样的优化处理。能一定程度上优化代码的运行速度。