leetcode 力扣 105 从前序与中序遍历序列构造二叉树

89 阅读1分钟

递归

lc105.jpeg 上图最右节点改为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;
    }
}