由於志鵬哥百度面試的時候被問到了這個問題了,所以還是覺得撕一波代碼的。先來個前+中,中+後的,額,前+後還沒考慮。
在重構二叉樹上,一般會有兩種詢問方式;
1.這兩個遍歷可以重構嗎?
2.重構的過程;
解答:1.關於由遍歷重構二叉樹,因爲中序遍歷的根節點的左邊是左子樹,而右邊是右子樹。同時若是問的二叉搜索樹,那麼中序可以說就是一個排序了。而前序遍歷的話,根節點就是首個。而後序遍歷的根節點則尾部;
2.關於如何重構,我使用的是遞歸的做法,詳情見代碼即可
前+中
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return helper(preorder,inorder,0,0,inorder.size()-1);
}
TreeNode* helper(vector<int>&preorder,vector<int>& inorder,int prestart,int instart,int inend){
//一個根本的就是找左右子樹的根節點,所以說白了,遞歸就是不要套進去,從第一個子問題分析完,就開始代入就好了
if(instart == inend){
return new TreeNode(preorder[prestart]);
}
if(instart>inend){
return NULL;
}
int cn = preorder[prestart];
TreeNode* Current = new TreeNode(cn);
int i_n = 0;
for(int i=0;i<=inorder.size()-1;i++){
if(inorder[i] == cn){
i_n = i;
break;
}
}
int ln = inorder[i_n];
Current->left = helper(preorder,inorder,prestart+1,instart,i_n-1);
Current->right = helper(preorder,inorder,prestart+i_n-instart+1,i_n+1,inend);
return Current;
}
};
中+後
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
return help(inorder,postorder,postorder.size()-1,0,inorder.size()-1);
}
TreeNode* help(vector<int>& inorder,vector<int> postorder,int pos,int inStart,int inEnd){
if(inStart>inEnd){
return NULL;
}
if(inStart==inEnd){
return new TreeNode(postorder[pos]);
}
int rv = postorder[pos];
TreeNode *root = new TreeNode(rv);
int tmppos=0;
for(;tmppos<inorder.size();tmppos++){
if(rv == inorder[tmppos]){
break;
}
}
root->left = help(inorder,postorder,pos-(inEnd-tmppos)-1,inStart,tmppos-1);
root->right = help(inorder,postorder,pos-1,tmppos+1,inEnd);
return root;
}
};