前序+中序、中序+后序构造二叉树

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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值