树
You are to determine the value of the leaf node in a given binary tree that is the terminal node of a
path of least value from the root of the binary tree to any leaf. The value of a path is the sum of values
of nodes along that path.
input
The input file will contain a description of the binary tree given as the inorder and postorder traversal
sequences of that tree. Your program will read two line (until end of file) from the input file. The first
line will contain the sequence of values associated with an inorder traversal of the tree and the second
line will contain the sequence of values associated with a postorder traversal of the tree. All values
will be different, greater than zero and less than 10000. You may assume that no binary tree will have
more than 10000 nodes or less than 1 node.
Output
For each tree description you should output the value of the leaf node of a path of least value. In the
case of multiple paths of least value you should pick the one with the least value on the terminal node.
Sample Input
3 2 1 4 5 7 6
3 1 2 5 6 7 4
7 8 11 3 5 16 12 18
8 3 11 7 16 18 12 5
255
255
Sample Output
1
3
255
#include <iostream>
#include <sstream>
#include <vector>
#define _ ios_base::sync_with_stdio(0),cin.tie(0)
using namespace std;
const int maxn=1e4+5;//复用
const int INF=0x7fffffff;
struct TreeNode{
int left=-1;
int right=-1;
}tree[maxn];
vector<int>in;
vector<int>post;
int build(int inL,int inR,int postL,int postR){
if(inL>inR)//越界情况 ,不需要构建
return -1;
int root=post[postR];//取当前序列的最后的值即为树(子树)根
int k;//中序序列中的根对应的下标
//in inL k-1 k k+1 inR
//leftNum = k-inL
//postL postL+leftNum-1 postL+leftNum postR-1 postR
for(int i=inL;i<=inR;i++){//找中序序列中的根对应的下标
if(root==in[i]){
k=i;
break;
}
}
int leftNum=k-inL;//根据中序序列找到左子树节点的个数
tree[root].left=build(inL,k-1,postL,postL+leftNum-1);//递归构建左子树
tree[root].right=build(k+1,inR,postL+leftNum,postR-1);//递归构建右子树
return root;//返回构建完左右子树的根
}
//void preOrderPrint(int root){
//
// if(~tree[root].left){
// preOrderPrint(tree[root].left);
// }
// if(~tree[root].right){
// preOrderPrint(tree[root].right);
// }cout<<root<<" ";
//}
int sum=INF;//最短路===>路径上所有的点和最小
int minLeaf=INF;//最小值路的最小叶子节点
void dfs(int root,int tempSum=0){
tempSum+=root;//求临时路径的值,存在“回溯复原状态,递归改变状态”的行为
if(tempSum>sum){
return ;
} //剪枝 如果临时路径的值已经大于当前路径的值,则无需多言
if(!(~tree[root].left)&&!(~tree[root].right)){
//!(~tree[root].left)成立代表,无左子树
// !(~tree[root].right)成立代表,无右子树
if( sum>tempSum || (minLeaf>root&&sum==tempSum)){
//1\当前最短路(走到叶子节点)的值小于假设的最短路的值(tempSum)
// ||
//2\当前最短路(走到叶子节点)的值等于假设的最短路的值(tempSum)
//且假设的最小的叶子节点值(minLeaf)大于当前的叶子节点
//满足以上两点之一,即代表需要更新
sum=tempSum;
minLeaf=root;
}
}
if(~tree[root].left)//递归查找左子树
dfs(tree[root].left,tempSum);
if(~tree[root].right)//递归查找左子树
dfs(tree[root].right,tempSum);
}
int main(){
stringstream ss;//构建输入流ss
string a,b;//a==>in b==>post
while(getline(cin,a)&&getline(cin,b)){//读入两个一整行包括空格的字符串
ss.clear(); //输入流清空
in.clear();//中序序列清空
post.clear();//后序序列清空
ss.str(a);//传入一个字符串,构建字符串流
int x;//临时变量,用来存放被空格分隔的数字
while(ss>>x){
in.push_back(x);//读入中序序列
}
ss.clear(); //输入流清空
ss.str(b);//传入一个字符串,构建字符串流
while(ss>>x){
post.push_back(x);//读入后序序列
}
build(0,in.size()-1,0,post.size()-1);//用中序和后序构建树
//求最小,所以初值置为INF无穷大 无穷小-INF
sum=INF;//最短路===>路径上所有的点和最小
minLeaf=INF;//最小的叶子节点值
dfs(post[post.size()-1]);//深搜求值(最小叶子节点的值)
cout<<minLeaf<<endl;//输出结果
}
return 0;
}