PAT (Advanced Level) Practice - 1151 LCA in a Binary Tree(30 分)

题目链接:点击打开链接

 

题目大意:给出中序序列和先序序列,再给出两个点,求这两个点的最近公共祖先。

 

解题思路:不用建树~已知某个树的根结点,若a和b在根结点的左边,则a和b的最近公共祖先在当前子树根结点的左子树寻找,如果a和b在当前子树根结点的两边,在当前子树的根结点就是a和b的最近公共祖先,如果a和b在当前子树根结点的右边,则a和b的最近公共祖先就在当前子树的右子树寻找。中序加先序可以唯一确定一棵树,在不构建树的情况下,在每一层的递归中,可以得到树的根结点,在此时并入lca算法可以确定两个结点的公共祖先~

注意:题目中 n 才是结点个数;pos 不能用数组开,因为存储位置的是利用该结点的值而不是下标,所以用ump。

 

AC 代码1(未建树版)

#include
#include

#define mem(a,b) memset(a,b,sizeof a)
#define ssclr(ss) ss.clear(), ss.str("")
#define INF 0x3f3f3f3f
#define MOD 1000000007

using namespace std;

typedef long long ll;

const int maxn=1e4+10;

int in[maxn], pre[maxn];
unordered_map pos;

void lca(int inl,int inr,int prel,int a,int b)
{
    if(inl>inr) return;
    int inRt=pos[pre[prel]], aIn=pos[a], bIn=pos[b];
    if(inRt>aIn && inRtbIn) printf("LCA of %d and %d is %d.\n", a, b, in[inRt]);
    else if(aIn==inRt || bIn==inRt) printf("%d is an ancestor of %d.\n", in[inRt], aIn==inRt ? b : a);
    else if(aIn>inRt && bIn>inRt) lca(inRt+1,inr,prel+1+(inRt-inl),a,b);
    else if(aIn

 

AC 代码2(建树-搜索版)

#include
#include

#define mem(a,b) memset(a,b,sizeof a)
#define ssclr(ss) ss.clear(), ss.str("")
#define INF 0x3f3f3f3f
#define MOD 1000000007

using namespace std;

typedef long long ll;

const int maxn=1e4+10;

struct node
{
    int d,l,r;
}T[maxn];

unordered_map vis;
int in[maxn], pre[maxn];

int create(int l1,int r1,int l2,int r2) // in pre
{
    if(l1>r1) return -1;
    int rt=l2;
    int p1=l1,p2;

    while(in[p1]!=pre[rt]) p1++;
    p2=p1-l1;
    T[rt].d=pre[rt];
    T[rt].l=create(l1,p1-1,l2+1,l2+p2);
    T[rt].r=create(p1+1,r1,l2+p2+1,r2);

    return rt;
}

int lca(int rt,int a,int b)
{
    if(rt==-1) return -1;
    if(a==T[rt].d || b==T[rt].d) return rt;
    int left=lca(T[rt].l,a,b);
    int right=lca(T[rt].r,a,b);
    if(left!=-1 && right!=-1) return rt;

    return left==-1 ? right : left;
}

int main()
{
    int n,q,a,b;
    scanf("%d%d",&q,&n);
    for(int i=0;i

 

AC 代码3(建树-LCA版)

#include
#include

#define mem(a,b) memset(a,b,sizeof a)
#define ssclr(ss) ss.clear(), ss.str("")
#define INF 0x3f3f3f3f
#define MOD 1000000007

using namespace std;

typedef long long ll;

const int maxn=1e4+10;

struct node
{
    int d,l,r;
}T[maxn];

unordered_map vis, lvl, fu;
int in[maxn], pre[maxn];

int create(int l1,int r1,int l2,int r2,int l,int f) // in pre
{
    if(l1>r1) return -1;
    int rt=l2;
    int p1=l1,p2;

    while(in[p1]!=pre[rt]) p1++;
    p2=p1-l1;
    T[rt].d=pre[rt];
    lvl[pre[rt]]=l;
    fu[pre[rt]]=f;
    T[rt].l=create(l1,p1-1,l2+1,l2+p2,l+1,pre[rt]);
    T[rt].r=create(p1+1,r1,l2+p2+1,r2,l+1,pre[rt]);

    return rt;
}

int lca(int a,int b)
{
    int root;
    if(a==b) return a;
    if(fu[a]==fu[b]) return fu[a];
    if(lvl[a]>lvl[b]) root=lca(fu[a],b);
    else root=lca(a,fu[b]);

    if(root!=-1) return root;
    return -1;
}

int main()
{
    int n,q,a,b;
    scanf("%d%d",&q,&n);
    for(int i=0;i

 

你可能感兴趣的:(#,ACM,#,PTA,#,DFS,#,树)