文章目录
思路
代码
MyMethod
用深度搜索的思想(好吧,前序、中序、后序都是深搜思想),保存寻找路径,看看找到2个节点的路径的重合部分,就可以找到最近公共祖先;
该方法实际上不需要遍历整棵树;
cpp
class Solution {
public:
vector<TreeNode*> path;
vector<vector<TreeNode*>> result;
void travel(TreeNode* cur, TreeNode* target)
{
if(cur == NULL)
{
return;
}
// 中
if(cur->val == target->val)
{
result.push_back(path);
return;
}
// 左
if(cur->left)
{
path.push_back(cur->left);
travel(cur->left, target);
path.pop_back();
}
// 右
if(cur->right)
{
path.push_back(cur->right);
travel(cur->right, target);
path.pop_back();
}
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q)
{
int i, j, min_length;
path.push_back(root);
travel(root, q);
path.clear();
path.push_back(root);
travel(root, p);
/*
for(i = 0; i < result.size(); i++)
{
for(j = 0; j < result[i].size(); j++)
{
cout << result[i][j]->val << ", ";
}
cout << endl;
}*/
// cout << "result[0].size() : " << result[0].size() << endl;
// cout << "result[1].size() : " << result[1].size() << endl;
min_length = min(result[0].size(), result[1].size());
for(i = 0; i < min_length; i++)
{
if(result[0][i]->val == result[1][i]->val)
{
continue;
}
else
{
break;
}
}
// cout << "i : " << i << "result[0][i] : " << result[0][i]->val;
return result[0][i-1];
}
};
Method 2
后序遍历,左、右、中。中间节点处理左右子树有没有找到孩子。
后序遍历很恰当的模拟了回溯的过程,需要遍历整棵树;
cpp
class Solution {
public:
TreeNode* travel(TreeNode* cur, TreeNode* p, TreeNode* q)
{
if(cur == p || cur == q || cur == NULL)
{
return cur;
}
// 左
TreeNode* left = travel(cur->left, p, q);
// 右
TreeNode* right = travel(cur->right, p, q);
// 中
if(left && right) // 找到了
{
return cur;
}
else if(left && right == NULL)
{
return left;
}
else // (left == NULL && right)
{
return right;
}
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
return travel(root, p, q);
}
};