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

简介: 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<bits/stdc++.h>#include<cmath>#define mem(a,b) memset(a,b,sizeof a)#define ssclr(ss) ss.clear(), ss.str("")#define INF 0x3f3f3f3f#define MOD 1000000007usingnamespacestd;
typedeflonglongll;
constintmaxn=1e4+10;
intin[maxn], pre[maxn];
unordered_map<int,int>pos;
voidlca(intinl,intinr,intprel,inta,intb)
{
if(inl>inr) return;
intinRt=pos[pre[prel]], aIn=pos[a], bIn=pos[b];
if(inRt>aIn&&inRt<bIn||inRt<aIn&&inRt>bIn) printf("LCA of %d and %d is %d.\n", a, b, in[inRt]);
elseif(aIn==inRt||bIn==inRt) printf("%d is an ancestor of %d.\n", in[inRt], aIn==inRt?b : a);
elseif(aIn>inRt&&bIn>inRt) lca(inRt+1,inr,prel+1+(inRt-inl),a,b);
elseif(aIn<inRt&&bIn<inRt) lca(inl,inRt-1,prel+1,a,b);
}
intmain()
{
intq,n,a,b;
scanf("%d%d",&q,&n);
for(inti=1;i<=n;i++) scanf("%d",&in[i]), pos[in[i]]=i;
for(inti=1;i<=n;i++) scanf("%d",&pre[i]);
while(q--)
    {
scanf("%d%d",&a,&b);
if(pos[a]==0&&pos[b]==0) printf("ERROR: %d and %d are not found.\n", a, b);
elseif(pos[a]==0||pos[b]==0) printf("ERROR: %d is not found.\n", pos[a] ==0?a : b);
elselca(1,n,1,a,b);
    }
return0;
}

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

#include<bits/stdc++.h>#include<cmath>#define mem(a,b) memset(a,b,sizeof a)#define ssclr(ss) ss.clear(), ss.str("")#define INF 0x3f3f3f3f#define MOD 1000000007usingnamespacestd;
typedeflonglongll;
constintmaxn=1e4+10;
structnode{
intd,l,r;
}T[maxn];
unordered_map<int,int>vis;
intin[maxn], pre[maxn];
intcreate(intl1,intr1,intl2,intr2) // in pre{
if(l1>r1) return-1;
intrt=l2;
intp1=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);
returnrt;
}
intlca(intrt,inta,intb)
{
if(rt==-1) return-1;
if(a==T[rt].d||b==T[rt].d) returnrt;
intleft=lca(T[rt].l,a,b);
intright=lca(T[rt].r,a,b);
if(left!=-1&&right!=-1) returnrt;
returnleft==-1?right : left;
}
intmain()
{
intn,q,a,b;
scanf("%d%d",&q,&n);
for(inti=0;i<n;i++) scanf("%d",&in[i]), vis[in[i]]=1;
for(inti=0;i<n;i++) scanf("%d",&pre[i]);
intrt=create(0,n-1,0,n-1);
while(q--)
    {
scanf("%d%d",&a,&b);
if(!vis[a] &&!vis[b]) printf("ERROR: %d and %d are not found.\n",a,b);
elseif(!vis[a] ||!vis[b]) printf("ERROR: %d is not found.\n",!vis[a]?a:b);
else        {
intminRt=lca(rt,a,b);
if(T[minRt].d==a||T[minRt].d==b) printf("%d is an ancestor of %d.\n",T[minRt].d,T[minRt].d==a?b:a);
elseprintf("LCA of %d and %d is %d.\n",a,b,T[minRt].d);
        }
    }
return0;
}

AC 代码3(建树-LCA版)

#include<bits/stdc++.h>#include<cmath>#define mem(a,b) memset(a,b,sizeof a)#define ssclr(ss) ss.clear(), ss.str("")#define INF 0x3f3f3f3f#define MOD 1000000007usingnamespacestd;
typedeflonglongll;
constintmaxn=1e4+10;
structnode{
intd,l,r;
}T[maxn];
unordered_map<int,int>vis, lvl, fu;
intin[maxn], pre[maxn];
intcreate(intl1,intr1,intl2,intr2,intl,intf) // in pre{
if(l1>r1) return-1;
intrt=l2;
intp1=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]);
returnrt;
}
intlca(inta,intb)
{
introot;
if(a==b) returna;
if(fu[a]==fu[b]) returnfu[a];
if(lvl[a]>lvl[b]) root=lca(fu[a],b);
elseroot=lca(a,fu[b]);
if(root!=-1) returnroot;
return-1;
}
intmain()
{
intn,q,a,b;
scanf("%d%d",&q,&n);
for(inti=0;i<n;i++) scanf("%d",&in[i]), vis[in[i]]=1;
for(inti=0;i<n;i++) scanf("%d",&pre[i]);
intrt=create(0,n-1,0,n-1,1,-1);
while(q--)
    {
scanf("%d%d",&a,&b);
if(!vis[a] &&!vis[b]) printf("ERROR: %d and %d are not found.\n",a,b);
elseif(!vis[a] ||!vis[b]) printf("ERROR: %d is not found.\n",!vis[a]?a:b);
else        {
intminRt=lca(a,b);
if(minRt==a||minRt==b) printf("%d is an ancestor of %d.\n",minRt,minRt==a?b:a);
elseprintf("LCA of %d and %d is %d.\n",a,b,minRt);
        }
    }
return0;
}
目录
相关文章
|
存储
LeetCode 107. Binary Tree Level Order Traversal II
给定二叉树,返回其节点值的自下而上级别顺序遍历。 (即,从左到右,逐下而上)。
79 0
LeetCode 107. Binary Tree Level Order Traversal II
|
存储
PAT (Advanced Level) Practice - 1057 Stack(30 分)
PAT (Advanced Level) Practice - 1057 Stack(30 分)
108 0
PAT (Advanced Level) Practice - 1057 Stack(30 分)
PAT (Advanced Level) Practice - 1127 ZigZagging on a Tree(30 分)
PAT (Advanced Level) Practice - 1127 ZigZagging on a Tree(30 分)
122 0
PAT (Advanced Level) Practice - 1043 Is It a Binary Search Tree(25 分)
PAT (Advanced Level) Practice - 1043 Is It a Binary Search Tree(25 分)
123 0
PAT (Advanced Level) Practice - 1138 Postorder Traversal(25 分)
PAT (Advanced Level) Practice - 1138 Postorder Traversal(25 分)
101 0
PAT (Advanced Level) Practice - 1068 Find More Coins(30 分)
PAT (Advanced Level) Practice - 1068 Find More Coins(30 分)
112 0
PAT (Advanced Level) Practice - 1010 Radix(25 分)
PAT (Advanced Level) Practice - 1010 Radix(25 分)
121 0
PAT (Advanced Level) Practice - 1143 Lowest Common Ancestor(30 分)
PAT (Advanced Level) Practice - 1143 Lowest Common Ancestor(30 分)
118 0
|
存储
PAT (Advanced Level) Practice - 1051 Pop Sequence(25 分)
PAT (Advanced Level) Practice - 1051 Pop Sequence(25 分)
100 0