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)前序遍歷和中序遍歷樹構造二叉樹
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.