题目
思路
需要不断的进行分别拆分先序遍历列表和后序遍历列表
中序列表的拆分根据先序列表的开头的元素分为左孩子和右孩子。
先序列表的拆分根据中序列表左孩子的元素个数和右孩子的元素个数。
不断的拆分下去。
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
unordered_map<int, int> maps;
for(int i=0;i<inorder.size();i++){
maps[inorder[i]] = i;
}
return dfs(preorder, inorder, 0,inorder.size()-1, 0,inorder.size()-1, maps);
}
TreeNode* dfs(vector<int>& preorder, vector<int>& inorder,
int left_preorder,int right_preorder,
int left_inorder, int right_inorder,
unordered_map<int, int>& maps
){
if(left_preorder>right_preorder) return nullptr;
TreeNode* root = new TreeNode(preorder[left_preorder]);
int pos = maps[preorder[left_preorder]];
// 左侧数量
int left_number = pos-left_inorder;
int right_number = right_inorder - pos;
root->left = dfs(preorder, inorder,
left_preorder+1, left_preorder+left_number,
left_inorder, pos-1,
maps
);
root->right = dfs(preorder, inorder,
left_preorder+left_number+1, right_preorder,
pos+1, right_inorder,
maps
);
return root;
}
};
从中序与后序遍历序列构造二叉树
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
unordered_map<int, int> maps;
for(int i=0;i<inorder.size();i++){
maps[inorder[i]] = i;
}
function<TreeNode*(int,int, int,int)> dfs = [&](int left_inor, int right_inor,
int left_pos, int right_pos
)-> TreeNode*{
if(left_pos>right_pos) return nullptr;
TreeNode* root_node = new TreeNode(postorder[right_pos]);
// 根据根节点将inor进行拆分
int pos = maps[postorder[right_pos]];
int right_number = right_inor - pos;
root_node->left = dfs(left_inor, pos-1, left_pos,right_pos-right_number-1);
root_node->right = dfs(pos+1, right_inor,right_pos-right_number, right_pos-1);
return root_node;
};
int n = inorder.size();
return dfs(0,n-1, 0,n-1);
}
};