【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);
			}
		}



	}
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章