先序+中序解法:

[1,2,3,4,5,6,7]       //先序

[3,2,4,1,6,5,7]       //中序

思路+步骤:


    一、以先序第一个值1建立根节点,它是整棵树的根。

    二、找到1在中序里面的下标:index
            中序下标index的左边都是左子树:n个元素,右边都是右子树

            同理,先序也有个分界点,分界点的左边都是左子树,右边都是右子树。如何求?
                    中序下标index左边有n个元素,先序就该在原来的基础上向右偏移n个元素求得左子树的上限:pre_left + n
                    即左子树下标范围为[pre_left + 1, pre_left + n],右子树下标范围为[pre_left + n + 1, size - 1]

            n如何求?
                     n = index - vin_pre //出界index - 入界vin_pre,即中序左子树有多少个元素

    三、给根的左节点结上左子树,即递归左子树范围。


    四、给根的右节点结上左子树,即递归右子树范围。

    五、当然,最后要在开始的地方加上递归终止条件:if(pre_left > pre_right) return NULL;

C++代码:
class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        return Rebuild(pre, 0, pre.size() - 1, vin, 0, vin.size() - 1);
    }
    //常引用减少复制
    TreeNode* Rebuild(const vector<int>& pre, int pre_left, int pre_right, const vector<int>& vin, int vin_left, int vin_right){
        //递归出口
        if(pre_left > pre_right) return NULL;
        
        //进来就以先序第一个值创建节点
        TreeNode* root =new TreeNode(pre[pre_left]);
        
        //找到先序第一个值在中序中的位置
        int index_pre_in_vin; 
        for(int i = vin_left; i <= vin_right; i++){
            if(root->val == vin[i]){
                index_pre_in_vin = i;
                break;
            }
        }
        
        //先序的左子树,和中序左子数数量是一样的,中序index左边有多少个元素,中序就应该向右偏移这么多。shift表示偏移。//右子树同理
        int shift = index_pre_in_vin - vin_left;
        
        //递归结左子树
        root->left = Rebuild(pre, pre_left + 1, pre_left + shift, vin, vin_left, index_pre_in_vin - 1);
        
        //递归结右子树
        root->right = Rebuild(pre, pre_left + shift + 1, pre_right, vin, index_pre_in_vin + 1, vin_right);
        
        return root;
    }
};

那么问题来了,怎么从中序、后序新建?

那么问题来了,怎么从中序、后序新建?
    
    后序和先序是反的
    先序:根左右,
    后序:左右根。
        
    思路1:
        从后面向前做,包括:实参递归区间、建立根节点从右1建立、递归出口。
        
    思路2:
        先中后序:根左右、左根右、左右根,,,,从左向右看和从右向左看是否是对称的?

        利用栈将后序:左右根,转换为:根右左
        利用栈将中序:左根右,转换为:右根左
        看起来很像先序+中序了
        只要创建时,先建立右子树,再建立左子树即可