题意:
给出一个二叉树的中序遍历和后序遍历的结果,还原构造出这颗树。
分析:
首先我们应该搞清楚中序遍历和后序遍历的原理。
其次,我们应该举个例子,用人脑的思维方式,来完成这个过程。再根据人脑的思维过程来思考怎么控制计算机来完成。
比如:
1
2 3
4 5 6 7
后序:452 673 1
中序:425 1 673
对于后序数组,我们发现,根节点一定在数组的最后一个,左右子树的根节点也在对应的子数组的最后一个。
对于中序数组,我们发现,根节点在中间某个位置,但是可以确定的是,左子树的结点都在根节点的左边,右子树的结点根节点都在右边
所以,我们可以倒序遍历后序数组,将第一个数来构造根节点。
将根节点的左结点设置为递归的结果,将根节点的右结点也设置为递归的结果。
递归的参数变化可以用角标来限定子数组区间。
同时我们可以利用根节点的值在中序数组中找到这个数。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public TreeNode buildTree(int[] inorder, int[] postorder) {
if(inorder.length==0 || postorder==null)
return null;
return helper(inorder, postorder, postorder.length-1, 0, inorder.length-1);
}
private TreeNode helper(int[] inorder, int[] postorder, int rootindex, int start, int end){
if(start > end){
return null;
}
int rootval = postorder[rootindex];
TreeNode root = new TreeNode(rootval);
int index = findRootInInorder(rootval, inorder, start, end);
int leftsize = end- index;
root.left = helper(inorder, postorder, rootindex-1-leftsize, start, index-1);
root.right = helper(inorder, postorder, rootindex-1, index+1, end);
return root;
}
private int findRootInInorder(int rootval, int[] inorder, int start, int end){
for(int i=start; i<=end; i++){
if(inorder[i] == rootval){
return i;
}
}
return -1;
}
}