1. 程式人生 > 其它 >圖解從前序與中序遍歷序列構造二叉樹

圖解從前序與中序遍歷序列構造二叉樹

技術標籤:力扣學習筆記二叉樹資料結構演算法leetcodec++

從前序與中序遍歷序列構造二叉樹

題目:

根據一棵樹的前序遍歷與中序遍歷構造二叉樹。 注意: 你可以假設樹中沒有重複的元素。 例如,給出 前序遍歷 preorder =[3,9,20,15,7] 中序遍歷 inorder = [9,3,15,20,7] 返回如下的二叉樹: 3 / \ 920 /\ 157 連結:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal

思路:


這兩個表格是前序和中序的遍歷陣列,我們定義 preorder 在閉區間[preStart,preEnd]內, inorder在閉區間[inStart,inEnd]內 第一步:先找到根節點,由先序遍歷可知根節點是前序遍歷陣列中的第一個元素,在上圖中標出,記根節點值rootVal為 preorder [ preStart ] 第二步,找到根節點值在中序遍歷陣列中的位置,記為index,使 inorder[index] == rootVal,如下圖所示 第三步:可以找到左子樹在陣列中的長度,如下圖所示: 由上述可知:9為根節點的左子樹,20,15,7節點為根節點的右子樹的節點,這是需要找到右子樹的根節點,然後去找到右子樹的左子樹和右子樹的右子樹來構造根節點下的右子樹。 於是我們在15,20,7中重複上述的一二三步,如下圖所示:
所以我們根據上述的分析步驟去遞迴實現程式碼,如下所示。

程式碼:

class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return buildHelp(preorder,0,preorder.size()-1,inorder,0,inorder.size()-1);
}
TreeNode *buildHelp(vector<int>& preorder,int preStart,int preEnd, vector<int>& inorder,int inStart,int inEnd)
{
if (preStart > preEnd)
{
return nullptr;
}
int rootVal = preorder[preStart];
int index = 0;
for (int i = inStart; i <= inEnd; i++)
{
if(inorder[i] == rootVal)
{
index = i;
break;
}
}
int leftSize = index - inStart;
TreeNode* root = new TreeNode(rootVal);
root->left = buildHelp(preorder, preStart + 1, preStart + leftSize,inorder, inStart, index - 1);
root->right = buildHelp(preorder, preStart + leftSize + 1, preEnd,inorder, index + 1, inEnd);
return root;
}
};