问题
思路
公共祖先,想法和前一道题目最初的做法一样。
找到他们两的路径,然后比较路径的最浅公共节点。
当然,有主意特殊数据的情形。
如果p和q在不在树里,显然没有公共父亲。
所以,虽然实际题意没有考虑这种情形,但是我应该考虑。
然后,在判断是否存在root==p || root==q这种情形,因为不用再比了。
肯定是公共节点了。
这个题有点烦的是getPath的实现,因为单纯传递vector好实现,但是接口不好设计。传递引用的时候,当前层返回,引用的状态不会更新,所以手动退出。
代码
/**
* 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;
std::vector<TreeNode*> path_p;
std::vector<TreeNode*> path_q;
bool flag = getPath(root, p, path_p);
if(!flag) return NULL;
flag = getPath(root, q, path_q);
if(!flag) return NULL;
if(root==p || root==q) return root;
int sz_p = path_p.size();
int sz_q = path_q.size();
for( int i = sz_p - 1; i >= 0; --i ){
for(int j = sz_q - 1; j >= 0; --j){
if(path_p[i] == path_q[j])
return path_p[i];
}
}
return NULL;
}
private:
bool getPath(TreeNode* root, TreeNode* p, std::vector<TreeNode*>& path){
if(!root) return false;
else{
path.push_back(root);
if(root == p) return true;
else{
bool left = getPath(root->left, p, path);
if(left) return true;
bool right = getPath(root->right, p, path);
if(!right) path.pop_back();//当前节点无效节点,返回上一层之前,退出向量。
return right;
}
}
}
};