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
思路
-
二叉樹的前序遍歷特徵:首個元素爲根,然後是左子樹和右子樹
-
二叉樹中序遍歷特徵:先是左子樹,然後根,最後是右子樹
-
因此可以先根據前序遍歷中根的值,找到中序遍歷根的索引, 這樣就可以在中序遍歷中找到左右子樹。
-
然後採用遞歸的思路,從葉子結點開始依次往上遞歸建樹,遞歸出口爲:當節點爲葉子節點或樹爲空時。
Java實現
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
return preIn(preorder, 0, preorder.length-1, inorder, 0, inorder.length-1);
}
public static TreeNode preIn(int[] preorder, int preLeft, int preRight, int[] inorder, int inLeft, int inRight) {
if (preorder.length == 0) {
return null;
}
// 創建根節點
TreeNode root = new TreeNode(preorder[preLeft]);
root.left = null;
root.right = null;
// 存儲左子樹的長度
int leftLength = 0;
// 存儲右子樹的長度
int rightLength = 0;
// 尋找左右子樹長度
for (int i = inLeft; i < inRight+1; i++) {
if (inorder[i] == root.val) {
leftLength = i- inLeft;
rightLength = inRight - inLeft + 1 - leftLength -1;
break;
}
}
if (leftLength > 0) {
root.left = preIn(preorder, preLeft+1, preLeft+1+leftLength-1, inorder, inLeft, inLeft+leftLength-1);
}
if (rightLength > 0) {
root.right = preIn(preorder, preLeft+1+leftLength, preRight, inorder, inLeft+leftLength-1+2, inRight);
}
return root;
}
}
Python實現
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def buildTree(self, preorder, inorder):
"""
:type preorder: List[int]
:type inorder: List[int]
:rtype: TreeNode
"""
return self.preIn(preorder, 0, len(preorder)-1, inorder, 0, len(inorder)-1)
def preIn(self, preorder, preLeft, preRight, inorder, inLeft, inRight):
"""
:type preorder: List[int]
:type preLeft: int
:type preRight: int
:type inorder: List[int]
:type inLeft: int
:type inRight: int
:rtype: TreeNode
"""
if len(preorder) == 0:
return None
# 創建節點
root = TreeNode(preorder[preLeft])
# 定義左子樹的長度
leftLength = 0
# 定義右子樹的長度
rightLength = 0
# 計算左右子樹的長度
for i in range(inLeft, inRight+1):
if inorder[i] == root.val:
leftLength = i - inLeft
rightLength = inRight - inLeft + 1 - leftLength - 1
break
# 構建左子樹
if leftLength > 0:
root.left = self.preIn(preorder, preLeft+1, preLeft+1+leftLength-1, inorder, inLeft, inLeft+leftLength-1)
# 構建右子樹
if rightLength > 0:
root.right = self.preIn(preorder, preLeft+1+leftLength, preRight, inorder, inLeft+leftLength-1+2, inRight)
return root
Scala實現
/**
* Definition for a binary tree node.
* class TreeNode(var _value: Int) {
* var value: Int = _value
* var left: TreeNode = null
* var right: TreeNode = null
* }
*/
object Solution {
def buildTree(preorder: Array[Int], inorder: Array[Int]): TreeNode = {
return preIn(preorder, 0, preorder.length-1, inorder, 0, inorder.length-1)
}
def preIn(preorder: Array[Int], preLeft: Int, preRight: Int, inorder: Array[Int], inLeft: Int, inRight: Int): TreeNode = {
if (preorder.length == 0) {
return null
}
// 創建節點
val root = new TreeNode(preorder(preLeft))
// 存儲左子樹的長度
var leftLength = 0
// 存儲右子樹的長度
var rightLength = 0
// 尋找左右子樹的長度
for (i <- inLeft to inRight) {
if (inorder(i) == root.value) {
leftLength = i - inLeft
rightLength = inRight - inLeft + 1 - leftLength - 1
}
}
if (leftLength > 0) {
root.left = preIn(preorder, preLeft+1, preLeft+1+leftLength-1, inorder, inLeft, inLeft+leftLength-1)
}
if (rightLength > 0) {
root.right = preIn(preorder, preLeft+1+leftLength, preRight, inorder, inLeft+leftLength-1+2, inRight)
}
return root
}
}