题目
剑指 Offer 07. 重建二叉树
我的思路
递归的思想来解决: 重复性的问题是: 输入preorder 和 inorder字符串 在inorder字符串中找到preorder首字符,把inorder字符串劈成2个子字符串 以inorder第一个子符串中的最后一个字符为边界,把preorder字符串也分成两个(用子字符串长度加上preorder第一个子串的起始位置即可) 再执行两次:create(root,pre1,in1);create(root,pre2,in2);
我的实现
/** * 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: void create(TreeNode* root,int pre_begin,int pre_end,int in_begin,int in_end,vector<int>& preorder, vector<int>& inorder){ printf("%d ",inorder[in_begin]); int root_val = preorder[pre_begin]; //root->val = root_val; if(pre_begin==pre_end) return;//递归出口条件 //在中序字符串中找到root_val,劈成两半 int i,k,temp; int j = pre_begin; for(i=in_begin;i<=in_end;i++){ if(inorder[i]==root_val) break; } printf("i=%d ",i); if(i>in_begin)//存在左子树 { //在前序子串中找到中序被劈开处前一个字符 temp = pre_begin; j = pre_begin+i-in_begin; root->left=new TreeNode(preorder[pre_begin+1]); printf("create:%d--%d,%d--%d",pre_begin+1,j,in_begin,i-1); create(root->left,pre_begin+1,j,in_begin,i-1,preorder,inorder); } if(i<in_end)//存在右子树 { //在前序子串中找到中序被劈开处后一个字符 root->right=new TreeNode(preorder[j+1]); create(root->right,j+1,pre_end,i+1,in_end,preorder,inorder); } } TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { if(preorder.size()==0)return NULL; TreeNode * root = new TreeNode(preorder[0]); //root->left=NULL;root->right=NULL; create(root,0,preorder.size()-1,0,preorder.size()-1,preorder,inorder); return root; } }; /* 递归的思想来解决: 重复性的问题是: 输入preorder 和 inorder字符串 在inorder字符串中找到preorder首字符,把inorder字符串劈成2个子字符串 以inorder第一个子符串中的最后一个字符为边界,把preorder字符串也分成两个(用子字符串长度加上preorder第一个子串的起始位置即可) 再执行两次:create(root,pre1,in1);create(root,pre2,in2); */
拓展学习
另一种思路(迭代)
转自官方题解
前序遍历的第一个元素是根,可以把中序遍历字符串劈开,分成左子树和右子树,很直观。
而中序遍历的第一个元素,是树的最左下节点。也可以看做是把前序遍历字符串劈开,分成从根一路左下到最左下节点 和 非这一路的子串。借助栈,处理!
比较难理解!
数组传参学会用迭代器
TreeNode* recursionBuild(vector<int>::iterator preBegin, vector<int>::iterator preEnd,vector<int>::iterator inBegin, vector<int>::iterator inEnd ) { ... recursionBuild(preBegin+1,preBegin+1+(root-inBegin),inBegin,root); ... }