105 Construct Binary Tree from Preorder and Inorder Traversal && 106 Construct Binary Tree from Inorder and Postorder Traversal

ss
5 min readJan 21, 2021

--

題目意思很簡單,給你前序跟中序, 要你組出一棵數

其實這個題目我印象很深刻, 這基本上是台灣考資工研究所的必考題, 這應該每個人都會寫, 但問題來了, 要怎麼用程式做呢

前序中序的基本概念這邊就不贅述了, 我們了解到

前序的第一個點一定是root

root能將中序分成左右子樹

於是我們我需要找到root在中序到底是位在哪個index, 即可將左右子樹給分出來

好問題來了, 如果找到root在中序的index, 要怎麼細分左子樹的頭尾, 跟右子樹的頭尾

我們先從左子樹開始

左:

preorder:

頭:preorder的頭index, 就是原本preorder_left + 1, 1是哪來的, preorder_left及為 root, 跳過這個root就是左子樹的頭

左preorder頭:preorder_left + 1

尾: 我們可以透過inorder找到的index, 判斷左子數的node數, 總共為 i — inorder_left個, 最後再從頭跑到尾 就是 preorder_left + i -inorder_left

左preorder尾: preorder_left+ i -inorder_left

inorder:

頭: 就是最左邊的值, inorder_left

左inorder頭: inorder_left

尾: root左邊那個就是了

左inorder尾: i -1

搞定了左子樹, 接下來換右子樹

右:

preorder:

頭: 就是剛剛左子樹preorder尾 + 1

右preorder頭: preorder_left+ i -inorder_left + 1

尾: preorder的最後一個

右preorder尾: preorder_right

inorder:

頭: root的右邊一位

右inorder頭: index+1

尾: inorder的最後一個

右inorder尾: inorder_right

code:

class Solution {
public:
TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder, int p_left,
int p_right, int i_left, int i_right) {
if (p_left > p_right || i_left > i_right) {
return nullptr;
}
int root_index = i_left; // in inorder, root index
int root_val = preorder[p_left];
for (; root_index <= i_right; root_index++) {
if (root_val == inorder[root_index]) {
break;
}
}
TreeNode *cur = new TreeNode(root_val);
int left_number = root_index - i_left;
cur->left = buildTree(preorder, inorder, p_left + 1,
p_left + left_number, i_left, root_index - 1);
cur->right = buildTree(preorder, inorder, p_left + left_number + 1,
p_right, root_index + 1, i_right);
return cur;
}
TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
return buildTree(preorder, inorder, 0, preorder.size() - 1, 0,
inorder.size() - 1);
}
};

中序後序的概念幾乎一樣, 就是找法要變動一下而已, 這邊就不多加說明了

class Solution {
public:
TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder,
int i_left, int i_right, int post_left,
int post_right) {
if (i_left > i_right || post_left > post_right) {
return nullptr;
}
int root_value = postorder[post_right];
int root_index = i_left; // root index in inorder vector
for (; root_index <= i_right; root_index++) {
if (root_value == inorder[root_index]) {
break;
}
}
TreeNode *root = new TreeNode(root_value);
int left_tree_number = root_index - i_left;
root->left = buildTree(inorder, postorder, i_left, root_index - 1,
post_left, post_left + left_tree_number - 1);
root->right = buildTree(inorder, postorder, root_index + 1, i_right,
post_left + left_tree_number, post_right - 1);
return root;
}
TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {
return buildTree(inorder, postorder, 0, inorder.size() - 1, 0,
postorder.size() - 1);
}
};

--

--

ss
ss

No responses yet