《劍指offer》-重建二叉樹

/*
 * 輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。
 * 假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。
 * 例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。
 * 思路:所謂的重建二叉樹,無非就是找到該二叉樹的根節點和左右節點
 */
public class ReConstructBinaryTree {
	/*法一:畫圖。1.拿到根節點在中序遍歷結果中的位置,該位置左邊是左子樹,右邊是右子樹
	 * 2.拿到左子樹的前序遍歷,中序遍歷結果。根據這兩個結果遞歸可以得到左子樹的根節點,即總的根節點的左節點
	 * 3.拿到右子樹的前序遍歷,中序遍歷結果。根據這兩個結果遞歸可以得到右子樹的根節點,即總的根節點的右節點
	 */
	public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
		if(pre.length <= 0)	
			return null;
		TreeNode root = new TreeNode(pre[0]);
		if(pre.length == 1)
			return root;
		
		//拿到根節點在中序遍歷結果中的位置
		int rootIndex = 0;
		for(int i = 0;i < in.length;i ++) {
			if(in[i] == root.val) {
				rootIndex = i;
				break;
			}
		}
		
		//拿到左子樹的前序遍歷,中序遍歷結果。根據這兩個結果遞歸可以得到左子樹的根節點,即總的根節點的左節點
		if(rootIndex > 0) {	//存在左子樹
			int[] prel = new int[rootIndex];
			int[] inl = new int[rootIndex];
			for(int i = 0;i < rootIndex;i ++) {
				prel[i] = pre[i + 1];
				inl[i] = in[i];
			}
			root.left = reConstructBinaryTree(prel, inl);
		}
		else {
			root.left = null;
		}
		
		//拿到右子樹的前序遍歷,中序遍歷結果。根據這兩個結果遞歸可以得到右子樹的根節點,即總的根節點的右節點
		if(rootIndex < in.length - 1) {	//存在右子樹
			int[] prer = new int[in.length - 1 - rootIndex];
			int[] inr = new int[in.length - 1 - rootIndex];
			for(int i = 0;i < in.length - 1 - rootIndex;i ++) {
				prer[i] = pre[i + rootIndex + 1];
				inr[i] = in[i + rootIndex + 1];
			}
			root.right = reConstructBinaryTree(prer, inr);
		}
		else {
			root.right = null;
		}
		
		return root;
	}
	
	//法二:需要畫圖計算起點和終點
	public TreeNode reConstructBinaryTree2(int [] pre,int [] in) {
		if(pre.length <= 0)	
			return null;
		return reConstruct(pre, 0, pre.length - 1, in, 0, in.length - 1);
	}
	
	public TreeNode reConstruct(int [] pre, int preStart, int preEnd, int [] in, int inStart, int inEnd) {
		if(preStart >= preEnd || inStart >= inEnd) {
			return null;
		}
		
		TreeNode root = new TreeNode(pre[preStart]);
		for(int i = 0;i < in.length;i ++) {
			if(root.val == in[i]) {		//找到根節點在中序遍歷結果中的位置
				root.left = reConstruct(pre, preStart + 1, preStart + i - inStart, in, inStart, i - 1);
				root.right = reConstruct(pre, preStart + i - inStart + 1, preEnd, in, i + 1, inEnd);
			}
		}
		
		return root;
	}
	
	public static void main(String[] args) {
		int [] pre = {1,2,4,5,3,6,7};
		int [] in = {4,2,5,1,6,3,7};
		TreeNode root = new ReConstructBinaryTree().reConstructBinaryTree2(pre, in);
		System.out.println(root.val + " " + root.left.val + " " + root.right.val);
	}
	
}

發佈了83 篇原創文章 · 獲贊 9 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章