問題描述:
Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
For example, given
preorder = [3,9,20,15,7]
inorder = [9,3,15,20,7]
Return the following binary tree:
3
/ \
9 20
/ \
15 7
解題思路:
特點:
先序遍歷的第一個節點爲樹根節點
中序遍歷中依據先序遍歷的根節點可以將整棵樹分割爲左子樹和右子樹兩個部分
1、通過先序遍歷找到第一個點作爲根節點,在中序遍歷中找到根節點並記錄rootIndex。
2、記錄左子樹的長度並在先序遍歷中依據這個長度找到左子樹的區間,用同樣方法可以找到右子樹的區間。
3、遞歸的建立左子樹和右子樹
代碼
class Solution {
/*找到根節點,劃分爲左右子樹序列,繼續的遞歸調用,直到所有的節點構造完成
* 1 [2 4 5] [3 6 7] [4 2 5] 1 [6 3 7]
*/
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
public TreeNode buildTree(int[] preorder, int[] inorder) {
int preLength = preorder.length;
int inLength = inorder.length;
return buildTree(preorder, 0, preLength-1, inorder, 0, inLength-1);
}
public TreeNode buildTree(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd) {
if(preStart > preEnd||inStart > inEnd) {
return null;
}
int rootVal = preorder[preStart];
int rootIndex = 0;
//在中序遍歷序列中找到根節點的值
for(int i = inStart; i <= inEnd; i++) {
if(rootVal == inorder[i]) {
rootIndex = i;
break;
}
}
TreeNode root = new TreeNode(rootVal);
//找到左子樹的長度
int len = rootIndex - inStart;
//將先序序列和中序序列分別分割爲左子樹的部分,繼續調用
root.left = buildTree(preorder, preStart+1, preStart+len, inorder, inStart, rootIndex-1);
//將先序序列和中序序列分別分割爲右子樹的部分,繼續調用
root.right = buildTree(preorder, preStart+len+1, preEnd, inorder, rootIndex+1, inEnd);
return root;
}
}