牛客網題目描述:java
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。數組
要求:時間限制:1秒 空間限制:32768Kspa
發現 劍指offer上的題目大部分都是遞歸玩。以前寫這個東西,一直不明白 什麼是重建二叉樹,昨晚忽然想起來,不就是想根據前序,中序兩種遍歷,還原樹嘛。。。知道題目要幹啥以後,就開始整理思路。code
首先是一些 名詞解釋吧:排序
前序: 又叫前根排序,就是先寫根節點,而後遍歷左子樹,而後遍歷右子樹。遞歸
中序: 又叫中根排序,就是先遍歷左子樹,根節點,而後遍歷右子樹。內存
後續:又叫後根排序,這個就不不說了吧。。。io
知道這個之後,拿着牛客網給的例子,進行畫圖:class
首先 前序數組,的第一位確定是一個根節點(只是說當這個節點是父節點,不說他是某個子節點)import
所以 前序的第一個 1 就是一個根節點。
而後根據 中序遍歷 的特色 根節點是 在遍歷完左子樹後,才遍歷的根節點。 所以,第一步是現將 總體的化爲根、左、右 三部分:如圖:
而後單獨拿出某個 子樹,例如 說 247 ,根據 前序:2 4 7 中序:4 7 2
得知 2 是 根, 4 7 都是 根節點2 的左邊。,如圖:
接着拿着單獨的 子樹 4 7 , 前序 4 7 中序 4 7
得知 7 是在 根節點 4 的右邊,如圖:
這樣,進行完整組合就是:
這樣就完整的 遞歸出了左邊的 樹。
而後一樣方法能夠算出 右邊 子樹的 分佈,到最後 完整的樹就能出來:
首先是如何 切割 數組,將數組分爲 左子樹,和右子樹,
因爲知道,前序的 第一個 是根, 而後根據中序遍歷,根 位置的 左邊的就是左子樹,右邊的 就是右子樹。
如:第一次傳入 的 前序爲: {1,2,4,7,3,5,6,8} 中序 爲: {4,7,2,1,5,3,8,6}
經過分割中序 中 1 前面的 , 後面的兩個數組,分別做爲左右子樹再分割就好。
分割後的前序: {2,4,7} 中序:{4,7,2} 前序:{3,5,6,8} 中序:{5,3,8,6}
總體的思想就是 根據 前序遍歷的數組的 第一個位置的數字 ,而後 劃分出 左右兩塊。
代碼:
節點: 牛客網提供
public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x){ val=x;} }
方法:
import java.util.Arrays; /** * 前序遍歷: 根左右 * 中序遍歷: 左根右 * 前: {1,2,4,7,3,5,6,8} * 中: {4,7,2,1,5,3,8,6} * Arrays.copyOfRange(arr,from,to) 第一個參數是被複制的數組,第二個是開始,第三個是結束。 * java中 全部的範圍好像 都是 [) 前閉後開,前包括,後不包括 * @author mzjwx * */ public class Solution { public static TreeNode reConstructBinaryTree(int [] pre,int [] in) { //前序數組 或者 中序數組的長度 爲0,就返回 null if(pre.length==0 || in.length==0){ return null; } //當前循環的根節點 int root=pre[0]; TreeNode treeNode=new TreeNode(root); //循環從中序數組中找到分割點 for(int i=0;i<in.length;i++){ if(in[i]==root){ //遞歸生成左子樹 treeNode.left=reConstructBinaryTree(Arrays.copyOfRange(pre, 1,i+1), Arrays.copyOfRange(in, 0, i)); //遞歸生成右子樹 treeNode.right=reConstructBinaryTree(Arrays.copyOfRange(pre, i+1,pre.length), Arrays.copyOfRange(in, i+1, in.length)); //返回當前節點 return treeNode; } } return null; } public static void main(String[] args) { int[] pre= {1,2,4,7,3,5,6,8}; int[] in={4,7,2,1,5,3,8,6}; TreeNode treeNode=reConstructBinaryTree(pre,in); } }
最開始經過的時候 是佔用內存 34000+K 明顯是不合要求的, 仔細看了一下代碼,原來是本身把new 操做放進了循環裏面。。。。
必定要細心。
感受 最主要的是,首先弄懂題目意思,而後是 本身先用本身的思路,在本子上 分步驟 一步一步畫出怎麼生成樹,越仔細越好, 而後就是將你思路變成代碼,最會注意邊界值,就行了。