对题霸题解的小小改进,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); } };