題目描述
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。
例如,給出
前序遍歷 preorder = [3,9,20,15,7]
中序遍歷 inorder = [9,3,15,20,7]
返回如下的二叉樹:
3
/ \
9 20
/ \
15 7
限制:
0 <= 節點個數 <= 5000
遞歸
本題直接利用的是二叉樹先序遍歷和中序遍歷的特點,通過遞歸來求解出答案。
1、通過先序遍歷,拿到第一個節點,即爲二叉樹根節點;
2、利用該根節點,算出左子樹節點數量,右子樹節點數量;
3、利用數量和根節點在中序節點中遍歷,分別算出當前二叉樹左右子樹的對應先序遍歷列表和中序遍歷列表;
4、遞歸求解;
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
private:
map<int, int> dis; //巧妙藉助了map,提高檢索性能,縮短時間
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
for(int i = 0; i < inorder.size(); i++){
dis[inorder[i]] = i;
}
return dfs(preorder, 0, preorder.size(), inorder, 0, inorder.size());
}
TreeNode* dfs(vector<int>& preorder, int preBegin, int preEnd, vector<int>& inorder, int inBegin, int inEnd){
if(preBegin >= preEnd || inBegin >= inEnd){
return nullptr;
}
TreeNode* root = new TreeNode(preorder[preBegin]);
int index = dis[preorder[preBegin]];
root->left = dfs(preorder, preBegin+1, preBegin+1+(index-inBegin), inorder, inBegin, index);
root->right = dfs(preorder, preBegin+1+(index-inBegin), preEnd, inorder, index+1, inEnd);
return root;
}
};