对题霸题解的小小改进,rebuild函数参数只需要 vin_left 、vin_right 和 前序 中序 两个数组即可。
这样可以显得代码更更优美一些。

题霸的rebiuld形参列表如:

TreeNode* rebuild(vector<int>& pre, int pre_left, int pre_right, vector<int>& vin, int vin_left, int vin_right)

在递归生成子树调用该函数时密密麻麻的一片实在吓到我了:

    root->left = rebuild(pre, pre_left+1, pre_left+i-vin_left, vin, vin_left, i-1);
    root->right = rebuild(pre, pre_left+i-vin_left+1, pre_right, vin, i+1, vin_right); 

事实上,递归调用函数的过程中,pre数组中的元素是按从左往右的顺序用于生成新的树节点Treenode的。
因此对于pre数组来说,只需维护一个 全局变量 pre_p记录当前使用到pre中的哪一个元素即可,而不必将其作为参数传入rebuild函数。

class Solution {
public:
    int pre_p=0;

    TreeNode* rebuild(int vin_left,int vin_right,vector<int> pre,vector<int> vin)
    {
       // printf("正在使用vin中%d-%d间的元素重建树\n",vin_left,vin_right);
        if(vin_left>vin_right) return nullptr;//数组中连一个数都没有了
        int mid = pre[pre_p];
        pre_p++;
        TreeNode *root = new TreeNode(mid);
        for(int i=vin_left;i<=vin_right;i++)
        {
            if(vin[i]==mid)
            {
                mid=i;
                break;
            }
        }
        //找到根节点在中序遍历中的下标;

        root->left=rebuild(vin_left, mid-1,pre,vin);
        root->right=rebuild(mid+1,vin_right,pre,vin);        
        return root;
    }

    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        return rebuild(0,pre.size()-1,pre,vin);
    }
};