题目
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
链接
答案
代码中有注释,可以看清思路。
大致意思就是:前序遍历的第一个节点是根节点,在中序遍历结果中查找到根节点后,可以将树分成左子树和右子树。再以相同的方式处理左子树和右子树。
在分出了左子树和右子树之后,可以得到左子树和右子树的长度,从而将前序遍历结果后面的序列一分为二。
代码
1 /** 2 * Definition for binary tree 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 private: 12 //在中序遍历的结果中查找指定值的位置,如果没有找到返回结束点 13 vector<int>::iterator findRoot(int val,vector<int>::iterator inBeg,vector<int>::iterator inEnd){ 14 vector<int>::iterator iter; 15 for(iter = inBeg;iter != inEnd; ++ iter){ 16 if(*iter == val){ 17 return iter; 18 } 19 } 20 21 return inEnd; 22 } 23 24 public: 25 //题目说“输入某二叉树的前序遍历和中序遍历的结果”,那么这两个列表的值应该是一样的 26 //暂时不考虑两个列表不相同的异常 27 struct TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> in) { 28 if(pre.empty() || in.empty()){ 29 return NULL; 30 } 31 return getRootOfBinaryTree(pre.begin(),pre.end(),in.begin(),in.end()); 32 } 33 34 TreeNode* getRootOfBinaryTree(vector<int>::iterator preBeg,vector<int>::iterator preEnd, 35 vector<int>::iterator inBeg,vector<int>::iterator inEnd){ 36 if(inBeg == inEnd){ 37 return NULL; 38 } 39 40 TreeNode *root = new TreeNode(*preBeg);//构建root节点 41 //前序遍历的第一个节点为根节点,在中序遍历的结果中查找到该值,则该值在中序中将树分为左子树和右子树 42 vector<int>::iterator findRootNode = findRoot(*preBeg,inBeg,inEnd); 43 //左子树节点的个数 44 int leftSize = findRootNode - inBeg; 45 //根节点后面的节点开始,长度为leftSize的为左子树的前序遍历结果 46 TreeNode *leftRoot = getRootOfBinaryTree(preBeg + 1,preBeg + 1 + leftSize, 47 inBeg,findRootNode); 48 //左子树前序遍历结果后面开始,为右子树的前序遍历结果 49 TreeNode *rightRoot = getRootOfBinaryTree(preBeg + 1 + leftSize,preEnd, 50 findRootNode + 1,inEnd); 51 52 if(leftRoot != NULL){ 53 root->left = leftRoot; 54 } 55 56 if(rightRoot != NULL){ 57 root->right = rightRoot; 58 } 59 return root; 60 } 61 };
浙公网安备 33010602011771号