题意: 同时给两个序列,分别是二叉树的中序遍历和后序遍历,求出根节点到叶子结点路径上的权值最小和 的那个 叶子节点的值,若有多个最小权值,则输出最小叶子结点的和。
想法: 一开始想着建树,但是没有这样建过,周赛题又出了一遍,没办法,后来尝试了一下,真的建出来了,也不难。
建树--->遍历二叉树----->over
注意: 这里必须是多组输入,否则就错了,记得吸收空格。
关于 先序遍历 根左右 后序遍历 左右根 中序遍历 左根右
遇到了几道 关于遍历的题,有点小体会,一般都是给出两种遍历结果,建树 或者 求另一种遍历顺序,但是每次都给出来中序遍历(没遇到过不给的,遇到了再说) 不管怎样,最重要的是(通过前序或者后序)找出根节点,然后(通过中序)分清左右子树是哪段区间,用指针来做 很方便,指向根节点就好。
看代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[10010],b[10010];
char s[10010];
struct node
{
int val;
node *lch,*rch;
};
struct qq
{
int val,leave;
} q[10100];
node *dfs(int *p1,int *p2,int n)传入中序首地址 后序的跟节点地址 中序数组长度
{
if(n<=0)
return NULL;
int i;
for(i=0; p2[0]!=p1[i]; i++);
node *q= new node;
q->val=p2[0]; q->rch=dfs(p1+i+1,p2-1,n-i-1); // 右 两个函数可以倒过来,无所谓
q->lch=dfs(p1,p2-n+i,i);//左
return q;
}
bool cmp(qq a,qq b)
{
if(a.val!=b.val)
return a.val<b.val;
return a.leave<b.leave;
}
int ww;
void found(node *p,int sum)//先序遍历二叉树
{
if(p==NULL)
return ;
sum+=p->val;
if(p->lch==NULL&&p->rch==NULL)
{
q[ww].val=sum;
q[ww++].leave=p->val;//储存路径值 和 叶子结点 值
//return ;
}
found(p->lch,sum);
found(p->rch,sum);
}
int main()
{
while(gets(s))//必须多组输入,注意吸收回车
{
ww=0;
int k=0,w=0;
for(int i=0; s[i]!='\0'; i++)
{
if(s[i]==' ')
{
a[w++]=k;
k=0;
}
else
k=k*10+s[i]-'0';
}
a[w++]=k;
for(int i=0; i<w; i++)
scanf("%d",&b[i]);
getchar();
node *p=dfs(a,b+w-1,w);
found(p,0);
sort(q,q+ww,cmp);
printf("%d\n",q[0].leave);
}
return 0;
}