1. 解题思路

  1. 首先要明白 先序,中序,后序遍历(就是根左右,左根右,左右根)
  2. 样例先序遍历:[1,2,3,4,5,6,7] 中序遍历:[3,2,4,1,6,5,7]
    1)起初范围就是整个先序列表和中序列表 ,先序的每个依次作为根节点
    2)首先是1 对应中序数组下标[3],则3,2,4为左子树的内容,6,5,7为右分支的内容
    图片说明

2. 源代码来自chain20190719194071

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* build(vector<int>& pre, int pre_left, int pre_right, vector<int>& vin, int vin_left, int vin_right) {
        if (pre_left > pre_right) return nullptr;//判断该准备做根的节点存在 
        int value = pre[pre_left];//取出当前根的值
        TreeNode* root = new TreeNode(value);//建立根节点

        for (int i = vin_left; i <= vin_right; ++i) {//i从中序开始找的位置  
            if (vin[i] == value) {//找到先序根节点对应的中序位置
            //这步 进行递归 寻找左右子树树 
            //根的左孩子指向节点为(先序根   )
                //参数1.传递完整先序队列参数
                //参数2.  本次先序根+1取新作为左子树根节点,但左子树其实不一定存在,需要划定右端点判断
                //参数3.  限定左子树在先序的右端点,当前根节点位置+左子树个数(当前在中序位置-开始中序开始的位置)
                //参数4.传递中序队列参数
                //参数5.  中序左端点不变
                //参数6.  中序变右边界(i-1)
                root->left = build(pre, pre_left + 1, pre_left + i - vin_left, vin, vin_left, i - 1);
            //根的右孩子指向节点为( )
                //参数1.先序队列不变 
                //参数2. 下个先序右节点=本次先序根+几个左子树(i-中序初始位置)+1,但右子树其实不一定存在,需要划定右端点判断
                //参数3. 限定右端点不变
                //参数4.中序队列不变 
                //参数5.  中序变左端点(i+1)  
                //参数6.  中序右边界不变
                root->right = build(pre, pre_left + i - vin_left+1, pre_right,vin, i + 1, vin_right);
                break;
            }
        }
        return root;
    }
    //返回头结点类型的  初始
    //参数1.先序遍历数组  
    //参数2.  每次先序的定根节点 首次为0  
    //参数3.  匹配先序右端点
    //参数4.中序遍历数组   
    //参数5.  中序开始找的位置 
    //参数6.  中序右端点
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        return build(pre, 0, pre.size() - 1, vin, 0, vin.size() - 1);//数组名
    }
};