题目描述
给定一棵二叉树(保证非空)以及这棵树上的两个节点对应的val值 o1 和 o2,请找到 o1 和 o2 的最近公共祖先节点。
数据范围:树上节点数满足 1≤n≤10^5, 节点值val满足区间 [0,n)
要求:时间复杂度 O(n)
注:本题保证二叉树中每个节点的val值均不相同。
dfs+栈
bool flag=false;
void dfs(TreeNode* cur,int target,stack<int> & stk)
{
stk.push(cur->val);
if(cur->val==target)
{
flag=true;
return;
}
if(cur->left)
{
dfs(cur->left, target, stk);
if(flag) return;
}
if(cur->right)
{
dfs(cur->right, target, stk);
if(flag) return;
}
stk.pop();
}
int lowestCommonAncestor(TreeNode* root, int o1, int o2) {
// write code here
stack<int> stk1;
stack<int> stk2;
dfs(root,o1,stk1);
flag=false;
dfs(root,o2,stk2);
int n1=stk1.size();
int n2=stk2.size();
cout<<endl;
if(n1>n2)
{
for(int i=0;i<n1-n2;++i) stk1.pop();
}
if(n2>n1)
{
for(int i=0;i<n2-n1;++i) stk2.pop();
}
while (true)
{
int t1=stk1.top();
stk1.pop();
int t2=stk2.top();
stk2.pop();
if(t1==t2) return t1;
}
}
用vector代替栈
bool flag=false;
void dfs(TreeNode* cur,int target,vector<int> & path)
{
path.push_back(cur->val);
if(cur->val==target)
{
flag=true;
return;
}
if(cur->left)
{
dfs(cur->left, target, path);
if(flag) return;
}
if(cur->right)
{
dfs(cur->right, target, path);
if(flag) return;
}
path.pop_back();
}
int lowestCommonAncestor(TreeNode* root, int o1, int o2) {
// write code here
vector<int> path1;
vector<int> path2;
dfs(root,o1,path1);
flag=false;
dfs(root,o2,path2);
int n1=path1.size();
int n2=path2.size();
int pre=path1[0];
for(int i=1;i<n1&&i<n2;++i)
{
if(path1[i]!=path2[i]) break;
pre=path1[i];
}
return pre;
}
递归法
int lowestCommonAncestor(TreeNode* root, int o1, int o2) {
// write code here
if(!root) return -1;
if(root->val==o1||root->val==o2) return root->val;
int left=lowestCommonAncestor(root->left, o1, o2);
int right=lowestCommonAncestor(root->right, o1, o2);
if(left==-1) return right;
if(right==-1) return left;
return root->val;
}