https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/
前序+中序
-  前序遍历,节点按照 [根左右]排序。
-  中序遍历,节点按照 [左根右]排序。
所以,确定某根后,可以根据中序遍历判断该根的左右节点区间。

通过结合前序遍历(确定根)和中序遍历(确定根的左右子树),可以构造出二叉树。
class Solution {
public:
    int n, idx;
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        TreeNode* root = nullptr;
        n = inorder.size();
    
        return dfs(root, preorder, inorder, 0, n - 1);
    }
    // 获取根在中序遍历中的下标
    int index(int v, vector<int>& inorder) {
        for(int i = 0; i < n; i++)
            if(v == inorder[i])
                return i;
        return -1;
    }
    TreeNode* dfs(TreeNode* root, vector<int>& preorder, vector<int>& inorder, int l, int r) {
        if(l > r)
            return nullptr;
        
        int v = preorder[idx++];
        int ind = index(v, inorder);
        
        // 前序:根左右。和idx++同向
        // 中序:左根右。
        // 下面初始化时也是先左后右,和idx++同向
        root = new TreeNode(v);
        root->left = dfs(root->left, preorder, inorder, l, ind - 1);
        root->right = dfs(root->right, preorder, inorder, ind + 1, r);
        return root;
    }
};
中序+后序
和上面类似。
-  后序遍历,节点按照 [左右根]排序。
-  中序遍历,节点按照 [左根右]排序。
所以,确定某根后,也可以根据中序遍历判断该根的左右节点区间。
代码区别也不大,需要注意的是idx的初值和构造顺序。后序遍历根是从后往前,即根右左,所以构造时也要符合这个顺序,先初始化右再初始化左。
class Solution {
public:
    int idx, n;
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        // idx初始值
        idx = n = inorder.size();
        TreeNode *root;
        return dfs(root, postorder, inorder, 0, n - 1);
    }
    // 获取根在中序遍历中的下标
    int index(int v, vector<int>& inorder) {
        for(int i = 0; i < n; i++)
            if(v == inorder[i])
                return i;
        return -1;
    }
    TreeNode* dfs(TreeNode* root, vector<int>& postorder, vector<int>& inorder, int l, int r) {
        if(l > r)
            return nullptr;
        int v = postorder[--idx];
        int ind = index(v, inorder);
        
        // 后序:左右根。和idx++同向
        // 中序:左根右。
        // 下面初始化时要按照先右后左的顺序,和idx++同向
        root = new TreeNode(v);
        root->right = dfs(root->right, postorder, inorder, ind + 1, r);
        root->left = dfs(root->left, postorder, inorder, l, ind - 1);
    
        return root;
    }
};



















