题目描述
给出一个二叉树如下图所示:
6
/ \
7 9
\ /
-2 6
请由该二叉树生成一个新的二叉树,它满足其树中的每个节点将包含原始树中的左子树和右子树的和。
20 (7-2+9+6)
/ \
-2 6
\ /
0 0
左子树表示该节点左侧叶子节点为根节点的一颗新树;右子树表示该节点右侧叶子节点为根节点的一颗新树
输入描述
2行整数,
第1行表示二叉树的中序遍历,
第2行表示二叉树的前序遍历,以空格分割
例如:
7 -2 6 6 9
6 7 -2 9 6
输出描述
1行整数,表示求和树的中序遍历,以空格分割
例如:
输出1 -2 0 20 0 6
示例1
输入:
-3 12 6 8 9 -10 -7
8 12 -3 6 -10 9 -7
输出:
0 3 0 7 0 2 0
思路
1 . 前序中序构造二叉树
前序: 中左右; 判断“中”是第一个元素。
中序: 根据前序找到的“中” ,判断左右子树是谁。(此时可以提前计算左右子树的和)
代码
public class Demo11 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 中序
int[] in = Arrays.stream(scanner.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
// 前序
int[] pre = Arrays.stream(scanner.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
// 最终中序结果
int[] resMid = new int[in.length];
buildTree(pre, in, resMid, 0, pre.length, 0, in.length);
System.out.println(Arrays.toString(resMid));
scanner.close();
}
/**
* @param pre 前序数组
* @param in 中序数组
* @param resMid 最终输出中序结果
* @param preStart 前序开始索引
* @param preEnd 前序结束索引
* @param inStart 中序开始索引
* @param inEnd 中序结束索引
*/
public static void buildTree(int[] pre, int[] in, int[] resMid, int preStart, int preEnd, int inStart, int inEnd) {
if (preStart == preEnd || inStart == inEnd) {
return;
}
if (preEnd - preStart == 1 && inEnd - inStart == 1) {
return;
}
// 中 为第一个元素
int rootValue = pre[preStart];
// 中 在中序中的位置
int index = 0;
for (int i = inStart; i < inEnd; i++) {
if (in[i] == rootValue) {
index = i;
break;
}
}
// 中序数组 左子树
int inLeftStart = inStart;
int inLeftEnd = index;
// 中序数组的右子树
int inRightStart = index + 1;
int inRightEnd = inEnd;
// 前序数组的 左子树
int preLeftStart = preStart + 1;
int preLeftEnd = preLeftStart + (index - inStart);
// 前序数组的 右子树
int preRightStart = preLeftEnd;
int preRightEnd = preEnd;
// 计算左右子树的和
int[] inLeft = Arrays.copyOfRange(in, inLeftStart, inLeftEnd);
int[] inRight = Arrays.copyOfRange(in, inRightStart, inRightEnd);
resMid[index] = Arrays.stream(inLeft).sum() +
Arrays.stream(inRight).sum();
// 递归
buildTree(pre, in, resMid, preLeftStart, preLeftEnd, inLeftStart, inLeftEnd);
buildTree(pre, in, resMid, preRightStart, preRightEnd, inRightStart, inRightEnd);
}
}