题目描述:
给出一个二叉树,输入两个树节点,求它们的最低公共祖先。一个树节点的祖先节点包括它本身。
注意:
- 输入的二叉树不为空;
- 输入的两个节点一定不为空,且是二叉树中的节点;
样例
二叉树[8, 12, 2, null, null, 6, 4, null, null, null, null]如下图所示:
8
/ \
12 2
/ \
6 4
1. 如果输入的树节点为2和12,则输出的最低公共祖先为树节点8。
2. 如果输入的树节点为2和6,则输出的最低公共祖先为树节点2。
分析:
本题是剑指offer的最后一题,一道常规的二叉树问题。二叉树的问题,一般要用递归解决。假设lowestCommonAncestor(root,p, q)这个函数具备求p,q最低公共祖先的问题,分析下如何转化为其子问题求解。如果p,q都在root的左子树,则解就在左子树,反之解在右子树。如果p和q一个在左子树,一个在右子树,那么解就是root。
这里无须区分到底找到的是p还是q,只要找到一个即可返回该结点。在某结点的左子树上找到了p,不继续深入查找了,在该结点右子树未找到q,题目保证一定有祖先,所以q一定在p的后代里。遍历到空节点表明没找到,遍历到p或者q就说明找到了,这是递归的两种边界情况。递归的主体如上所述,只在左子树上找到了则返回左子树,两棵子树都找到了则返回root。由于递归的性质,遍历到解了才开始回溯,所以返回的就是最低公共祖先。
/**
* 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) {
if(!root) return NULL;
if(root == p || root == q) return root;
auto l = lowestCommonAncestor(root->left,p,q);
auto r = lowestCommonAncestor(root->right,p,q);
if(l && r) return root;
if(l) return l;
if(r) return r;
}
};
|