【leetcode】Array——Construct Binary Tree from Preorder and Inorder Traversal(105)

题目:

Given preorder and inorder traversal of a tree, construct the binary tree.

Note:
You may assume that duplicates do not exist in the tree.

思路:使用递归。

preorder[0]是整个tree的root,在inerder中定位root,左侧的是leftTree或者leftchild,右侧的是rightTree或者rightchild。

通过root在preorder中的位置以及左右树的节点数,可以在preorder中分别定位各自的子树的root。

举个栗子:

preorder:A B D E C F      inorder: D B E A F C

root为A,inorder定位A后,划分两部分,左树是D B E,右树是F C,分别递归。

左树的root可以通过preorder定位:原rootIndex+1即为B,再把左树划分。

右树的root在preorder的位置:原rootIndex+(左侧树的节点数)+1

递归的过程中,会维护inorder两个index:left和right,left和right之间构成一个子树,带解析。

左/右树的节点数,就是 left和right之间被root划分后两侧的长度。(详细见代码理解)

代码:

public class Construct_Binary_Tree_from_Preorder_and_Inorder_Traversal {
	public int [] preorder;
	public int [] inorder;

	public TreeNode buildTree(int[] preorder, int[] inorder) {
		this.preorder = preorder;
		this.inorder = inorder;
		if(preorder==null||preorder.length==0)
			return null;
		TreeNode root = new TreeNode(preorder[0]);
		divideInorder(preorder[0], 0, root ,0,inorder.length-1);
		return root;
	}

	private void divideInorder(int rootInt,int rootIntIndex,TreeNode root,int left,int right){
		for(int i=left;i<=right;i++){
			if(inorder[i]==rootInt){
				if(i>left){
					int leftRootInt = preorder[rootIntIndex+1];
					TreeNode leftNode = new TreeNode(leftRootInt);
					root.left=leftNode;
					if(left+1<i){
						//存在left子树
						divideInorder(leftRootInt,rootIntIndex+1,leftNode,left,i-1);
					}
				}
				if(i<right){
					int rightRootInt = preorder[rootIntIndex+i-left+1];
					TreeNode rightNode = new TreeNode(rightRootInt);
					root.right=rightNode;
					if(i+1<right){
						//存在right子树
						divideInorder(rightRootInt, rootIntIndex+i-left+1, rightNode, i+1, right);
					}
				}
			}
		}

	}
}
思路(改进):用HashMap存放inorder信息,这样在preorder中定位根节点后可以直接查询map就可知root在inorder中的位置,不用再次遍历。

public class Construct_Binary_Tree_from_Preorder_and_Inorder_Traversal {
	public int [] preorder;
	public Map<Integer,Integer> inorderMap = new HashMap<>();

	public TreeNode buildTree(int[] preorder, int[] inorder) {
		this.preorder = preorder;
		if(preorder==null||preorder.length==0)
			return null;
		for(int i=0;i<inorder.length;i++)
			inorderMap.put(inorder[i], i);

		TreeNode root = new TreeNode(preorder[0]);
		divideInorder(preorder[0], 0, root ,0,inorder.length-1);
		return root;
	}

	private void divideInorder(int rootInt,int rootIntIndex,TreeNode root,int left,int right){
		int i = inorderMap.get(rootInt);
		if(i>left){
			int leftRootInt = preorder[rootIntIndex+1];
			TreeNode leftNode = new TreeNode(leftRootInt);
			root.left=leftNode;
			if(left+1<i){
				//存在left子树
				divideInorder(leftRootInt,rootIntIndex+1,leftNode,left,i-1);
			}
		}
		if(i<right){
			int rightRootInt = preorder[rootIntIndex+i-left+1];
			TreeNode rightNode = new TreeNode(rightRootInt);
			root.right=rightNode;
			if(i+1<right){
				//存在right子树
				divideInorder(rightRootInt, rootIntIndex+i-left+1, rightNode, i+1, right);
			}
		}



	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值