Given inorder and postorder traversal of a tree, construct the binary tree.
这道题要记住这个算法。
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
private int findPosition(int[] arr, int start, int end, int key) {
int i;
for (i = start; i <= end; i++) {
if (arr[i] == key) {
return i;
}
}
return -1;
}
private TreeNode myBuildTree(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 = findPosition(inorder, instart, inend, postorder[postend]);
root.left = myBuildTree(inorder, instart, position - 1,
postorder, poststart, poststart + position - instart - 1);//后根遍历中[0,index-1]就是左子树的节点,[index,lenth-1]就是右子树的节点
root.right = myBuildTree(inorder, position + 1, inend,
postorder, position - inend + postend, postend - 1);//这里非常重要
return root;
}
public TreeNode buildTree(int[] inorder, int[] postorder) {
if (inorder.length != postorder.length) {
return null;
}
return myBuildTree(inorder, 0, inorder.length - 1, postorder, 0, postorder.length - 1);
}
}
题意:根据中根遍历结果与后根遍历结果求出原来的树
分析:1.如何根据树得中根与后根求树,简单说明一下:
(1)后根遍历的最后一个节点是该树的根;
(2)在中根遍历中找到该节点,下标记为index,该节点将树左右分开
(3)后根遍历中[0,index-1]就是左子树的节点,[index,lenth-1]就是右子树的节点
(4)分别对左子树和右子树进行递归求解
2.在这道题目中,我犯了几个典型错误:
(1)左右子树的坐标范围求错,如程序中,假设inorder中,根节点为i,则左子树的节点数为i-in_s,由于postorder左子树的起点为in_s,则终点为i-1;postorder右子树的起点为post_s+i-ins,终点为post_e-1。其中,postorder中右子树的起点我犯了错误,想当然的认为是i,后来发现应该是相对位移。
(2)函数调用中的引用问题,TreeNode* &root,我刚开始的时候没有加引用,提交的结果全都是空,哎~没有加引用,并没有改变最初始的root值。