思路:亮点是递归构造二叉树,还有就是有一个非常重要的知道点,某个子树后序遍历的最后一个结点一定是该子树的根结点,而中序遍历中左子树全位于根结点的左侧,右子树全位于根结点的右侧
二叉树问题一般都可以使用递归算法,注意理清楚递归的用意
package test;
public class Test{
static class Node{//节点,也可以用数组
int value;
Node left,right;
@Override
public String toString() {
return value+"";
}
}
static int[] in_order;
static int[] post_order;
/**
* 根据后序遍历和中序遍历构造数
* @param L1
* @param R1
* @param L2
* @param R2
* @return
*/
static Node build(int L1,int R1,int L2,int R2){
if(L1>R1) return null;
int root = post_order[R2];//找出根节点
int p = L1;
while(in_order[p]!=root){//查找根节点在中序遍历中的位置
p++;
}
int cnt = p-L1;
Node n = new Node();//生成根节点
n.value = root;
n.left = build(L1,p-1, L2, L2+cnt-1);//继续生成左子树
n.right = build(p+1, R1, L2+cnt, R2-1);//继续生成右子树
return n;
}
static int best;//记录最佳子节点
static int best_sum = 10000000;//记录最短权重
/**
* 该函数的作用是查找以u为根节点到叶子节点的最短权重
* 使用递归的方法,假设这个函数有这样的功能
* 我们只需传根节点进去,然后判断该节点是否存在左右子节点
* @param u
* @param sum
*/
public static void dfs(Node u,int sum){
sum += u.value;//每次递归,加上节点的值
if(u.left==null && u.right==null){//如果不存在左右节点,说明是叶子节点
if(sum<best_sum || (sum==best_sum&&u.value <best)){//判断跟新最佳权重
best = u.value;
best_sum = sum;
}
}
if(u.left!=null) dfs(u.left,sum);//如果存在左子树,继续计算左子树
if(u.right!=null) dfs(u.right,sum);//如果存在右子树,继续计算右子树
}
public static void main(String[] args) {
//模拟数据,输入略
int n= 7;
in_order = new int[]{3,2,1,4,5,7,6};
post_order = new int[]{3,1,2,5,6,7,4};
Node root = build(0, n-1, 0, n-1);
dfs(root,0);
System.out.println(best);
}
}