题目
查看题目
解题思路
主要思路:递归思想。
主要考虑的问题:
- 根据前序和中序遍历恢复二叉树的基本思想
- 每次怎样划分preorder数组进行遍历
主要步骤以及细节:
- 前序遍历数组中,从头开始,每一个都是节点,可以用来区分左右子树。
- 找到前序遍历数组中的第一个元素,通过该值定位到中序遍历中与该点值相同位置的索引(无论是哪一种遍历,数组中的元素都是一样的,显然的)
- 记录索引为idx,此时idx在中序遍历数组中已经将数组分成两半。
- 使用递归,在下一次的递归中:左子树,对于preorder数组来说,从上一次的preLeft的下一个开始,遍历的长度不会超过中序遍历数组中idx的长度,即(idx - inLeft)。对inorder数组来说,从初识的inLeft开始到idx - 1的位置
- 右子树,对于preorder数组来说,从左子树边界的下一个开始,到最后preRight。对inorder数组来说,从idx的下一个元素开始,到inorder的最后,也就是inRight
代码
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
return helper(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
}
public TreeNode helper(int[] preorder, int preLeft, int preRight,
int[] inorder, int inLeft, int inRight){
if (inLeft > inRight || preLeft > preRight) {
return null;
}
int idx = 0;
int val = preorder[preLeft];
TreeNode root = new TreeNode(val);
for(int i = inLeft; i <= inRight; i++){
if (inorder[i] == val){
idx = i;
break;
}
}
root.left = helper(preorder, preLeft + 1, preLeft + (idx - inLeft),
inorder,inLeft ,idx - 1);
root.right = helper(preorder, preLeft + (idx - inLeft) + 1, preRight,
inorder, idx + 1, inRight);
return root;
}
}