递归
上图最右节点改为7
这题最难的理解的地方就是递归函数的参数为什么要这样设置
先递归左子树:
preLeft + 1: 可以看作根节点指针,在preorder中从左往右遍历,构建根节点,+ 1 是为了向右移动
leftSubtreeSize: 在inorder中确定左子树的大小
peLeft + leftSubtreeSize: 左子树的右边界
inLeft: 右子树的左边界
inRoot - 1: 右子树的右边界,在代码中没有作用,凑数的
再递归右子树:
preLeft + leftSubtreeSize + 1: 根节点指针
preRight: 左子树的右边界
inRoot + 1: 右子树的左边界,+ 1 是为了跳过根节点
class Solution {
Map<Integer, Integer> inorderMap = new HashMap<>();
public TreeNode buildTree(int[] preorder, int[] inorder) {
int n = preorder.length;
for (int i = 0; i < n; i++) {
inorderMap.put(inorder[i], i);
}
return myBuildTree(preorder, inorder, 0, n - 1, 0, n - 1);
}
public TreeNode myBuildTree(int[] preorder, int[] inorder, int preLeft, int preRight, int inLeft, int inRight) {
if (preLeft > preRight) {
return null;
}
int preRoot = preLeft;
TreeNode root = new TreeNode(preorder[preRoot]);
int inRoot = inorderMap.get(preorder[preRoot]);
int leftSubtreeSize = inRoot - inLeft;
root.left = myBuildTree(preorder, inorder, preLeft + 1, preLeft + leftSubtreeSize, inLeft, inRoot - 1);
root.right = myBuildTree(preorder, inorder, preLeft + leftSubtreeSize + 1, preRight, inRoot + 1, inRight);
return root;
}
}