重建二叉樹

牛客網題目描述:java

輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。數組

要求:時間限制:1秒 空間限制:32768Kspa

發現 劍指offer上的題目大部分都是遞歸玩。以前寫這個東西,一直不明白 什麼是重建二叉樹,昨晚忽然想起來,不就是想根據前序,中序兩種遍歷,還原樹嘛。。。知道題目要幹啥以後,就開始整理思路。code

首先是一些 名詞解釋吧:排序

前序:  又叫前根排序,就是先寫根節點,而後遍歷左子樹,而後遍歷右子樹。遞歸

中序: 又叫中根排序,就是先遍歷左子樹,根節點,而後遍歷右子樹。內存

後續:又叫後根排序,這個就不不說了吧。。。io

 

知道這個之後,拿着牛客網給的例子,進行畫圖:class

step1:

首先 前序數組,的第一位確定是一個根節點(只是說當這個節點是父節點,不說他是某個子節點)import

所以 前序的第一個 1 就是一個根節點。

step2:

而後根據 中序遍歷 的特色 根節點是 在遍歷完左子樹後,才遍歷的根節點。 所以,第一步是現將 總體的化爲根、左、右 三部分:如圖:

 

而後單獨拿出某個 子樹,例如 說 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 操做放進了循環裏面。。。。

必定要細心。

最後:

感受 最主要的是,首先弄懂題目意思,而後是 本身先用本身的思路,在本子上 分步驟 一步一步畫出怎麼生成樹,越仔細越好, 而後就是將你思路變成代碼,最會注意邊界值,就行了。

相關文章
相關標籤/搜索