Description
Solutions
某顆樹的先序遍歷:ABCDEFG,中序遍歷:CBDAFGE。首先由先序遍歷的第一個節點A可以得知(先序遍歷的特點):這棵樹的根節點爲A;
根據中序遍歷可以得到A節點左邊的節點BCD爲左子樹節點(先序BCD,中序CBD),A節點右邊的節點EFG爲右子樹節點(先序EFG,中序FGE)。
對於左子樹BCD,左子樹的根節點爲B,由中序遍歷得知B節點左邊的節點C屬於左子樹,右邊節點D屬於右子樹;
以此類推。。。。。。採用深度遞歸方式構造整棵樹。
Code
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
算法如下:
public TreeNode reConstructBinaryTree(int[] pre, int[] in) {
// 輸入數據合法性校驗
if (pre == null || in == null || pre.length != in.length) {
return null;
}
// 進入構造樹的遞歸函數
return buildTree(pre, in);
}
public TreeNode buildTree(int[] pre, int[] in) {
// 每次創建子樹的根節點
TreeNode result = new TreeNode(pre[0]);
// 如果該子樹只有一個節點則直接返回該樹
// 否則需要遞歸設置左右子樹
if (pre.length != 1) {
int i = 0;
for (; i < in.length; i++) {
if (pre[0] == in[i]) {
break;
}
}
// 如果有左子樹,則構造左子樹,其中Arrays.copyOfRange用於避免索引越界判斷麻煩,
// 當然也可以使用左右邊界索引代替copyOfRange,這樣的話輸入參數會很多
// 例如:buildTree(int[] pre, int[] in, int start1, int end1, int start2, int end2)
if (i > 0) {
result.left = buildTree(Arrays.copyOfRange(pre, 1, i + 1), Arrays.copyOfRange(in, 0, i));
}
if (i < pre.length - 1) {
result.right = buildTree(Arrays.copyOfRange(pre, i + 1, pre.length), Arrays.copyOfRange(in, i + 1, in.length));
}
}
return result;
}