class Solution {
/**'
* '
*@param preorder : A list of integers that preorder traversal of a tree
*@param inorder : A list of integers that inorder traversal of a tree
*@return : Root of a tree
*/
public:
//获取一个元素在vector中的下标
int getLoc(vector<int >& ino, int ele){
for ( int i = 0; i < ino.size( ); i++ ){
if ( ino[i] == ele ){
return i;
}
}
return -1;
}
//是否在左边子树中
bool IsInChildLeftTree(int ele, int s, int e, vector<int> v){
for ( int i = s; i < e; i++ ){
if ( ele == v[i] )
return true;
}
return false;
}
public:
//找到右子树的根节点
//s:中序遍历中左子树的起点
//incurpos:当前子树根节点在中序遍历的位置,是查找的终点
//precurpos:当前子树根节点在前序遍历的位置 ,也是左子树的终点
int findRightRoot(vector<int> pre, vector<int> ino, int s, int precurpos, int incurpos)
{
int i = precurpos + 1; //当前根的起点,是在前序遍历中的
while ( i < pre.size( ) && IsInChildLeftTree(pre[i], s, incurpos, ino) == true ){ //如果处于左子树中,下标增加
i++;
}
if ( i >= pre.size( ) )return -1;
return i;
}
//s:子树起点
//e:子树终点,这两个都是指在中序遍历中的位置
//precurpos:当前子树根节点的在前序遍历中的位置
//incurpos:当前子树根节点在中序遍历的位置
//node:传入的根节点
TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
// write your code here
TreeNode* root = NULL;
if ( preorder.size( ) == 0 )
return NULL;
buildTree(preorder, inorder, 0, preorder.size( ), 0, getLoc(inorder, preorder[0]), root);
return root;
}
//s,e指定了区间长度
//precurpos:当前根在前序遍历中的位置
//incurpos:当前根在中序遍历中的位置
void buildTree(vector<int> &preorder, vector<int> &inorder, int s, int e, int precurpos, int incurpos, TreeNode*& node) {
static int* inblocked = new int[preorder.size( )]; //保存当前已经构造完毕的节点
if ( s >= e || precurpos > preorder.size( ) || incurpos > preorder.size( ) || e > preorder.size( ) ){
node = NULL;
return;
}
node = new TreeNode(preorder[precurpos]);//当前节点已经构造,不用再次构造
int currentblockloc = getLoc(inorder, preorder[precurpos]);
inblocked[currentblockloc] = 1;//所以不用再次构造,blocked=1
//cout << "constructing node:" << node->val << endl;
//从先序遍历中找到右边子节点
int tmprightcur = findRightRoot(preorder, inorder, s, precurpos, incurpos);
int ttt; //找到当前节点在中序遍历中的位置,这个位置可以将中序遍历的序列分为左边和右边
ttt= getLoc(inorder, preorder[precurpos]);
//cout << "start from:" << s << "end with:" << ttt << endl;
//如果当前左边已经到边界,或者已经有值,那么左边不用处理
if ( !( currentblockloc < 0 || (currentblockloc>0&& inblocked[currentblockloc - 1] == 1 ) ) && precurpos + 1<preorder.size() )
buildTree(preorder, inorder, s, ttt, precurpos + 1, getLoc(inorder, preorder[precurpos + 1]), node->left);
//cout << "start from:" << ttt << "end with:" << tmprightcur << endl;
//如果当前右边已经到了边界,或者已经有值,那么右边不用处理
if ( !( currentblockloc >= preorder.size() || (currentblockloc<preorder.size()-1&& inblocked[currentblockloc + 1] == 1)&&tmprightcur!=-1 )
&& tmprightcur<preorder.size() )
buildTree(preorder, inorder, ttt,e, tmprightcur,getLoc(inorder,preorder[tmprightcur]), node->right);
}
void DisplayTree(TreeNode* root){
if ( root == NULL )
return;
cout << root->val << endl;
DisplayTree(root->left);
DisplayTree(root->right);
}
};
LintCode-剑指Offer-(73)前序遍历和中序遍历树构造二叉树
最新推荐文章于 2020-08-23 08:08:14 发布