《剑指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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章