1.问题描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回
二叉树节点结构如下:
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
2.基本思路
前序遍历序列设为A;后续遍历序列设为B。
从递归上讲:
- 找到根节点r
- 找到r的左子节点
- 找到r的右子节点
本质上:不断的划分集合A和集合B
- 根据前序遍历集合A找根节点r
- 而后根据中序遍历集合B找r的左子树中序遍历集合B_left,r右子树中序遍历集合B_right
- 再在集合A中找r的左子树前序遍历序列A_left,r的右子树前序遍历集合A_right
结合上面的想法,则递归步骤如下:
- 找到根节点r,划分集合A,集合B
- 在A_left和B_left中找r的左子节点
- 在A_right和B_right中找r的右子节点
3.代码
递归代码
TreeNode* helpReconstructBinaryTree(vector<int>& pre,int plow,int phigh,vector<int>& vin,int vlow,int vhigh){ if(phigh<plow || vhigh<vlow) return NULL; TreeNode *head=new TreeNode(pre[plow]); int i=0; // 一定要注意这里的i表示的是间隔 while(vin[vlow+i]!=pre[plow]){ ++i; } head->left=helpReconstructBinaryTree(pre,plow+1,plow+i,vin,vlow,vlow+i-1); head->right=helpReconstructBinaryTree(pre,plow+i+1,phigh,vin,vlow+i+1,vhigh); return head; } TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) { if(pre.empty() || vin.empty()) return NULL; TreeNode *head=helpReconstructBinaryTree(pre,0,pre.size()-1,vin,0,vin.size()-1); return head; }