105. Construct Binary Tree from Preorder and Inorder Traversal
- 1 minutes read - 468 wordsLeetcode 105. Construct Binary Tree from Preorder and Inorder Traversal
題目
Given two integer arrays preorder and inorder where preorder is the preorder traversal of a binary tree and inorder is the inorder traversal of the same tree, construct and return the binary tree.
想法
用前序遍歷及中序遍歷的結果反推二元樹的結構。
前序遍歷 (pre-order) 就是先去根節點,再去左節點,最後右節點。
中序遍歷 (in-order) 則是先去左節點,再去根節點,最後右節點。
二元樹的特色是:每個節點及其子節點都是二元樹。
所以我們可以從最上面的根節點,分左右遞迴建置子樹。
依前序遍歷的特性可以知道 preorder[0] 就是根節點(的值)。
依該值去反查 inorder[x],則 inorder[x - 1] 就會是它的左子節點(的值),而 inorder[x + 1] 則會是它的右子節點(的值)。
以左右子節點為子樹的根節點,遞迴下去建立子樹,最後回傳最上面的根節點就可以了。
實作
Javascript
var buildTree = function (preorder, inorder) {
// 以便從節點 value 來反查在 inorder 中的位置
let inorder_location = new Map();
for (let i = 0; i < inorder.length; i++) inorder_location.set(inorder[i], i);
function tree_build(preorder_root_location, inorder_left_bound, inorder_right_bound) {
// 建構 root 節點,獲取 root 在 inorder 的位置
let root_value = preorder[preorder_root_location],
root = new TreeNode(root_value),
inorder_root_location = inorder_location.get(root_value);
// 以左子節點為 root 建構子樹
if (inorder_root_location > inorder_left_bound)
root.left = tree_build(preorder_root_location + 1, inorder_left_bound, inorder_root_location - 1);
// 以右子節點為 root 建構子樹
if (inorder_root_location < inorder_right_bound)
root.right = tree_build(preorder_root_location + inorder_root_location - inorder_left_bound + 1, inorder_root_location + 1, inorder_right_bound);
// 回傳 root,包含其子樹
return root;
}
// 開始建構這棵樹,從最上方根節點 (preorder[0]) 開始做,inorder 的範圍為整個的 inorder
return tree_build(0, 0, inorder.length - 1);
};