题目:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
假设输入的前序遍历和中序遍历结果中都不含重复的数字。
例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并输出它的后序遍历序列。
二叉树的定义如下:
struct BinaryTreeNode{ int val; BinaryTreeNode* left; BinaryTreeNode* right; BinaryTreeNode(int x):val(x),left(NULL),right(NULL){} };
思路:
在二叉树的先序遍历序列中,第一个数总是数的根结点的值,后面依次是是左子树结点的值、右子树结点的值;
在二叉树的中序遍历序列中,根节点位于序列中间,根节点左边为左子树,右边为右子树。
根据上述信息,我们可以:
先通过先序遍历序列找到根节点,
然后在中序遍历序列中找到根节点,这样就可以确定左子树和右子树。
接着再回到先序遍历序列中找到左子树和右子树,重复上述步骤(递归)。
代码:
struct BinaryTreeNode{ int val; BinaryTreeNode* left; BinaryTreeNode* right; BinaryTreeNode(int x):val(x),left(NULL),right(NULL){} }; BinaryTreeNode* ConstructCore(int* startPreorder,int* endPreorder,int* startInorder,int* endInorder){ int rootValue=startPreorder[0]; BinaryTreeNode* root=new BinaryTreeNode(rootValue); if(startPreorder==endPreorder && startInorder==endInorder) return root; // else // throw std::exception("Invalid Input.\n"); int* rootInorder=startInorder; while(rootInorder!=endInorder && *rootInorder!=rootValue) ++rootInorder; // if(rootInorder==endInorder && *rootInorder!=rootValue) // throw std::exception("Invalid Input.\n"); int leftLength=rootInorder-startInorder; int* leftPreOrderEnd=startPreorder+leftLength; if(leftLength>0) root->left=ConstructCore(startPreorder+1,leftPreOrderEnd,startInorder,rootInorder-1); int rightLength=endPreorder-startPreorder-leftLength; if(rightLength>0) root->right=ConstructCore(leftPreOrderEnd+1,endPreorder,rootInorder+1,endInorder); return root; } BinaryTreeNode* Construct(int* preOrder,int* inOrder,int length){ if(preOrder==NULL || inOrder==NULL || length<=0) return NULL; return ConstructCore(preOrder,preOrder+length-1,inOrder,inOrder+length-1); }
在线测试OJ:
http://www.nowcoder.com/books/coding-interviews/8a19cbe657394eeaac2f6ea9b0f6fcf6?rp=1
AC代码:
/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: struct TreeNode* construct(const vector<int> &pre,int startPre,int endPre,const vector<int> &in,int startIn,int endIn){ int rootValue=pre[startPre]; TreeNode* root=new TreeNode(rootValue); if(startPre==endPre && startIn==endIn) return root; int rootIndex=startIn; while(rootIndex<=endIn && in[rootIndex]!=rootValue) rootIndex++; int leftLength=rootIndex-startIn; if(leftLength>0) root->left=construct(pre,startPre+1,startPre+leftLength,in,startIn,rootIndex-1); int rightLength=endPre-startPre-leftLength; if(rightLength>0) root->right=construct(pre,startPre+leftLength+1,endPre,in,rootIndex+1,endIn); return root; } struct TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> in) { int len=pre.size(); if(len<=0) return NULL; return construct(pre,0,len-1,in,0,len-1); } };