1. 程式人生 > >Leetcode--從中序與後序遍歷構造二叉樹

Leetcode--從中序與後序遍歷構造二叉樹

根據一棵樹的中序遍歷與後序遍歷構造一顆二叉樹。

例如:

中序遍歷 inorder = [9,3,15,20,7]
後序遍歷 postorder = [9,15,7,20,3]

返回如下的二叉樹:

    3
   / \
  9  20
    /  \
   15   7

解題思路:

中序遍歷的順序為 左子節點 -> 根節點 -> 右子節點,中序遍歷的結果如圖所示:

後序遍歷的順序為 左子節點 -> 右子節點 -> 根子節點,後序遍歷的結果如圖所示:

可以看出,後序遍歷的最後一個元素就是整棵樹的根節點,通過查詢根節點在中序遍歷中的位置,可以找出左子樹和右子樹的範圍,根據左右子樹在中序遍歷中的位置,可以判斷出左右子樹在後序遍歷中的位置,這樣,我們就得到了根節點以及左右子樹的中序遍歷和後序遍歷。根據這個思路進行遞迴,就可得到最終結果。

程式碼如下:

public class BuildTree {
	private static class TreeNode{
		int val;
		TreeNode left;
		TreeNode right;
		TreeNode(int val){
			this.val=val;
		}
	}
	
	private static TreeNode solve(int[] inorder,int[] postorder) {
		if(inorder.length==0) return null;
		return search(inorder,0,inorder.length,postorder,0,postorder.length);
	}
	
	private static TreeNode search(int[] inorder,int instart,int inend,int[] postorder,int poststart,int postend) {
		if(instart>inend) return null;
		 TreeNode root=new TreeNode(postorder[postend]);
		 int position=searchPosition(inorder,instart,inend,postorder[postend]);
		 root.left=search(inorder,instart,position-1,postorder,poststart,poststart+(position-instart-1));
		 root.right=search(inorder,position+1,inend,postorder,poststart+position-instart,postend-1);
		 return root;
	}
	
	private static int searchPosition(int[] inorder,int instart,int inend,int key) {
		for(int i=instart;i<=inend;i++) {
			if(inorder[i]==key) return i;
		}
		return -1;
	}

}