解题思路:对于给定的二叉树的中序遍历和后序遍历,可以构造出这棵二叉树,方法是根据后序遍历找到树根。然后在中序遍历中找到树根,从而找出左右子树的结点列表,然后递归构造左右子树。
本题最不容易理解的就是构造树,当然需要耐下心来仔细理解
- #include<iostream>
- #include<string>
- #include<sstream>
- using namespace std;
- const int maxn=10000+10;
- int in_order[maxn],post_order[maxn]; //中序序列和后序序列
- int lson[maxn],rson[maxn]; //左子树,右子树数组
- int n;
- bool read(int *t){ //读取数字序列
- string str;
- if(!getline(cin,str))return false;
- stringstream ss(str);
- n=0;
- int temp;
- while(ss>>temp)t[n++]=temp;
- return true;
- }
- int buildtree(int l1,int r1,int l2,int r2){ //通过中、后序序列创建树 in_order[l1.......r1], post_order[l2.........r2];
- if(l1>r1)return 0; //当为树叶时,即无左右子树(lson[root]=0,rson[root]=0),返回0;
- int root=post_order[r2];
- int temp=l1;
- while(in_order[temp]!=root)temp++; //找到树根
- int lt=temp-l1; //左子树个数
- lson[root]=buildtree(l1,temp-1,l2,l2+lt-1);
- rson[root]=buildtree(temp+1,r1,l2+lt,r2-1);
- return root;
- }
- int best,best_sum; //当前树叶最优,当前权之和最优
- void dfs(int temp,int sum){ //dfs深度优先遍历
- sum+=temp;
- if(!lson[temp] && !rson[temp]){ //树叶
- if(sum<best_sum || sum==best_sum&&temp<best ){
- best_sum=sum;
- best=temp;
- }
- }
- if(lson[temp])dfs(lson[temp],sum);
- if(rson[temp])dfs(rson[temp],sum);
- }
- int main(){
- while(read(in_order)){
- read(post_order);
- buildtree(0,n-1,0,n-1);
- best=best_sum=1000000000;
- dfs(post_order[n-1],0);
- cout<<best<<endl;
- }
- return 0;
- }
解题思路:对于给定的二叉树的中序遍历和后序遍历,可以构造出这棵二叉树,方法是根据后序遍历找到树根。然后在中序遍历中找到树根,从而找出左右子树的结点列表,然后递归构造左右子树。
本题最不容易理解的就是构造树,当然需要耐下心来仔细理解