889.根据前序和后序遍历构造二叉树
思路:
本题思路和105,106思路略有不同,但也有相似的地方。
- 前序数组的第一位和后序数组的最后一位相同,都是根节点,并且一个在首位,一个在末尾,根据此根节点判断不出来 左右子树
- 前序数组第二个元素是左子树的根节点,在后序数组中找到该根节点即可找出 左子树范围和右子树范围。
- 再根据后序数组的下一个元素判断 左子树的孩子和右子树的孩子,依此类推。
注意点:
-
本题前序数组第一位并不能区分左右子树,所以应该 用第二个元素来区分。
-
用第二个元素时,递归到后面必会越界,设置条件防止越界
代码实现
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
HashMap<Integer, Integer> postHashMap = new HashMap<Integer, Integer>();
int[] pre;
public TreeNode constructFromPrePost(int[] preorder, int[] postorder) {
for (int i = 0; i < postorder.length; i++) {
postHashMap.put(postorder[i], i);
}
pre = preorder;
return buildTree(0, postorder.length - 1, 0, preorder.length - 1);
}
public TreeNode buildTree(int post_start, int post_end, int pre_start, int pre_end) {
if (post_start > post_end || pre_start > pre_end) return null;
int root = pre[pre_start];
TreeNode node = new TreeNode(root);
if (pre_start == pre_end) return node;
int index = postHashMap.get(pre[pre_start + 1]);
node.left = buildTree(post_start, index, pre_start + 1, pre_start + index - post_start + 1);
node.right = buildTree(index + 1, post_end - 1, pre_start + index - post_start + 2, pre_end);
return node;
}
}