二叉树的最近公共祖先
若为传统的tree_node求解问题*
基本思路:
采取DFS方式,对于当前节点,研究是否为目标节点的一个。然后根据递归子问题的返回,若其中一个子树返回2,那么说明问题已经在子树中解决,否则,计算子树返回的数目+当前节点是否为目标点的数目。最后返回
若为多组目标点求解问题
基本思路:
首先通过DFS建立每个节点=》节点level深度的映射。同时建立每个节点=》父亲节点的映射。(物理存储可能采取map或者数组方式)
然后LCA算法过程,首先研究两个点是否在同一Level。如果不在,将低Level的点沿着父亲节点方向移动。直到两个点在同一Level。最后两者一起向父亲节点移动,直到相等(重合)
代码实现
#include<iostream>
#include<vector>
using namespace std;
struct node
{
int l;
int r;
int level;
int parent=-1;
};
void dfs(vector<node>&arr,int root,int level) //由root开始生成每棵树的level
{
if(root==0)
return;
arr[root].level=level;
dfs(arr,arr[root].l,level+1);
dfs(arr,arr[root].r,level+1);
}
int LCA(vector<node>&arr,int o1,int o2) //寻找o1 o2的最近祖先
{
while(o1!=o2)
{
if(arr[o1].level>arr[o2].level) //o1更低
{
o1=arr[o1].parent;
}
else if(arr[o1].level<arr[o2].level)
{
o2=arr[o2].parent;
}
else
{
o1=arr[o1].parent;
o2=arr[o2].parent; //两者一起向上
}
}
return o1;
}
int main()
{
int n,root;
cin>>n>>root;
vector<node> arr(n+1);
for(int i=0;i<n;i++)
{
int fa,lc,rc;
cin>>fa>>lc>>rc;
arr[fa].l=lc;
arr[fa].r=rc;
if(lc)
arr[lc].parent=fa;
if(rc)
arr[rc].parent=fa;
}
dfs(arr,root,1);
int m;
cin>>m;
while(m--)
{
int o1,o2;
cin>>o1>>o2;
cout<<LCA(arr,o1,o2)<<endl;
}
}