題目:
Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
題解:
1 / \ 2 3 / \ / \ 4 5 6 7
對於上圖的樹來說,
index: 0 1 2 3 4 5 6
先序遍歷為: 1 2 4 5 3 6 7
中序遍歷為: 4 2 5 1 6 3 7
為了清晰表示,我給節點上了顏色,紅色是根節點,藍色為左子樹,綠色為右子樹。
可以發現的規律是:
1. 先序遍歷的從左數第一個為整棵樹的根節點。
2. 中序遍歷中根節點是左子樹右子樹的分割點。
再看這個樹的左子樹:
先序遍歷為: 2 4 5
中序遍歷為: 4 2 5
依然可以套用上面發現的規律。
右子樹:
先序遍歷為: 3 6 7
中序遍歷為: 6 3 7
也是可以套用上面的規律的。
所以這道題可以用遞迴的方法解決。
具體解決方法是:
通過先序遍歷找到第一個點作為根節點,在中序遍歷中找到根節點並記錄index。
因為中序遍歷中根節點左邊為左子樹,所以可以記錄左子樹的長度並在先序遍歷中依據這個長度找到左子樹的區間,用同樣方法可以找到右子樹的區間。
遞迴的建立好左子樹和右子樹就好。
程式碼如下:
1 public TreeNode buildTree(int[] preorder, int[] inorder) {
2 int preLength = preorder.length;
3 int inLength = inorder.length;
4 return buildTree(preorder, 0, preLength-1, inorder, 0, inLength-1);
5 }
6
7 public TreeNode buildTree(int[] pre, int preStart, int preEnd, int[] in, int inStart, int inEnd){
8 if(inStart > inEnd || preStart > preEnd)
9 return null;
10
11 int rootVal = pre[preStart];
12 int rootIndex = 0;
13 for(int i = inStart; i <= inEnd; i++){
14 if(in[i] == rootVal){
15 rootIndex = i;
16 break;
17 }
18 }
19
20 int len = rootIndex - inStart;
21 TreeNode root = new TreeNode(rootVal);
22 root.left = buildTree(pre, preStart+1, preStart+len, in, inStart, rootIndex-1);
23 root.right = buildTree(pre, preStart+len+1, preEnd, in, rootIndex+1, inEnd);
24
25 return root;
26 }
2 int preLength = preorder.length;
3 int inLength = inorder.length;
4 return buildTree(preorder, 0, preLength-1, inorder, 0, inLength-1);
5 }
6
7 public TreeNode buildTree(int[] pre, int preStart, int preEnd, int[] in, int inStart, int inEnd){
8 if(inStart > inEnd || preStart > preEnd)
9 return null;
10
11 int rootVal = pre[preStart];
12 int rootIndex = 0;
13 for(int i = inStart; i <= inEnd; i++){
14 if(in[i] == rootVal){
15 rootIndex = i;
16 break;
17 }
18 }
19
20 int len = rootIndex - inStart;
21 TreeNode root = new TreeNode(rootVal);
22 root.left = buildTree(pre, preStart+1, preStart+len, in, inStart, rootIndex-1);
23 root.right = buildTree(pre, preStart+len+1, preEnd, in, rootIndex+1, inEnd);
24
25 return root;
26 }
Reference:http://edwardliwashu.blogspot.com/2013/01/construct-binary-tree-from-preorder-and.html