牛客網刷題筆記記錄。參考自:
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列和中序遍歷序列,則重建二叉樹並返回。
通常樹有如下幾種遍歷方式:
本題為前序遍歷和中序遍歷,最少需要兩種遍歷方式,才能重建二叉樹。
前序遍歷序列中,第乙個數字總是樹的根結點的值。在中序遍歷序列中,根結點的值在序列的中間,左子樹的結點的值位於根結點的值的左邊,而右子樹的結點的值位於根結點的值的右邊。剩下的我們可以遞迴來實現,具體如圖:
我的c++實現:雖然可以正確執行,然有著明顯的可優化空間(我忘記了前序遍歷陣列的乙個特點:根節點後所有的左子樹元素都緊挨在一起),其中的巢狀迴圈完全是多餘的並且大大增加了程式執行的時間複雜度!!!!
/**
* definition for binary tree
* struct treenode
* };
*/class solution
treenode * node=new treenode(pre[0]);
//定義左右自樹的前序遍歷陣列和中序遍歷陣列
vectorl_pre,r_pre,l_vin,r_vin;
//計算各個陣列的值
int root_index=0;//根結點在中序遍歷陣列中的位置
while(vin[root_index]!=pre[0])
//確定左右子樹的中序遍歷陣列
for(int i=0;iroot_index)
}//確定左右子樹的前序遍歷陣列
for(int i=0,j=0;ileft=reconstructbinarytree(l_pre,l_vin);
node->right=reconstructbinarytree(r_pre,r_vin);
return node;}};
乙個更好的c++實現:
/**
* definition for binary tree
* struct treenode
* };
*/class solution
//依次是前序遍歷左子樹,前序遍歷右子樹,中序遍歷左子樹,中序遍歷右子樹
vectorleft_pre, right_pre, left_vin, right_vin;
//中序遍歷第乙個節點一定為根節點
treenode* head = new treenode(pre[0]);
//找到中序遍歷的根節點
int root = 0;
//遍歷找到中序遍歷根節點索引值
for(int i = 0; i < pre.size(); i++)
}//利用中序遍歷的根節點,對二叉樹節點進行歸併
for(int i = 0; i < root; i++)
for(int i = root + 1; i < pre.size(); i++)
//遞迴,再對其進行上述所有步驟,即再區分子樹的左、右子子數,直到葉節點
head->left = reconstructbinarytree(left_pre, left_vin);
head->right = reconstructbinarytree(right_pre, right_vin);
return head;}};
劍指offer(四) 重建二叉樹
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列和中序遍歷序列,則重建二叉樹並返回。我們先來弄懂前序遍歷和中序遍歷的特點 前序遍歷 根結點 左子樹 右子樹。中序遍歷 左子樹 根結點 右子樹。所以前序遍歷序列的第乙個值...
劍指Offer 四 重建二叉樹
解法1 前序遍歷的第乙個數為樹的根,而中序遍歷中根所在位置的左面的序列即為左子樹的中序遍歷,右面即為右子樹的中序遍歷,遞迴找到每個子樹的根就ok了!class solution 返回構造的treenode根節點 def reconstructbinarytree self,pre,tin write...
劍指Offer 四 重建二叉樹
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列和中序遍歷序列,則重建二叉樹並返回。coding utf 8 class treenode def init self,x self.val x self.left n...