通过以上三步,可确定 三个节点 :1.树的根节点、2.左子树根节点、3.右子树根节点。 对于树的左、右子树,仍可使用以上步骤划分子树的左右子树。
分治算法解析:
递推参数: 当前树的根节点 root 、当前树的左边界 left 、当前树的右边界 right ;
终止条件: 当 left > right ,代表已经越过叶节点,此时返回 null ;
递推工作:
- 建立根节点 node : 节点值为 preorder[root] ;
- 划分左右子树: 查找根节点在中序遍历 inorder 中的索引 i ;
- 构建左右子树: 开启左右子树递归;
/**
* 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 {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
this->preorder = preorder;
for(int i = 0; i < inorder.size(); i++){
//利用哈希表 查找根节点在中序遍历 inorder 中的索引 i
dic[inorder[i]] = i;
}
return recur(0, 0, inorder.size() - 1);
}
private:
vector<int> preorder;
unordered_map<int,int> dic;
TreeNode* recur(int root, int left, int right){
//递归终止条件
if (left > right) return nullptr;
TreeNode *node = new TreeNode(preorder[root]);
//根节点在中序遍历序列中的位置
int i = dic[preorder[root]];
node->left = recur(root+1, left, i-1); //左子树递归
//右子树根节点索引:根节点索引 + 左子树长度 + 1
node->right = recur(root+i-left+1, i+1, right);
return node;
}
};