从前序与中序遍历序列构造二叉树

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal
给定一棵树的前序遍历 preorder 与中序遍历 inorder。请构造二叉树并返回其根节点。
示例 1:
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
示例 2:
Input: preorder = [-1], inorder = [-1]
Output: [-1]
提示:
1 <= preorder.length <= 3000
inorder.length == preorder.length
-3000 <= preorder[i], inorder[i] <= 3000
preorder 和 inorder 均无重复元素
inorder 均出现在 preorder
preorder 保证为二叉树的前序遍历序列
inorder 保证为二叉树的中序遍历序列

思路:前序遍历是根左右,中序遍历是左根右,所以前序遍历第一个一定是根,我们可以在中序遍历找到这个根,并一分为二,左边是左子树,右边是右子树,这样能建成一个根。左子树,右子树暂时不清楚具体,但是长度能确定。所以前序遍历除去根后也能一分为二。左子树的数字正好与中序遍历形成了相对应的长度。这样一个大问题就变成了一个小问题。这样再继续划分,直到最后一个,然后回溯的过程就建成了一棵树,直接输出即可。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int length;
    TreeNode* dfs(vector<int>&preorder, vector<int>& inorder, int pl, int pr, int il, int ir)
    {

        int i, shu, wei, chang;
        /*if (preorder.size() < 1) return nullptr;不可以,因为vector数组永远不变的
        if (inorder.size() < 1) return nullptr;
        if (pl >= length) return nullptr;*/
        if (pl > pr) return nullptr;
        if (il > ir) return nullptr;
        shu = preorder[pl];
        for (i = il; i <= ir; i++){
            if (inorder[i] == shu){
                wei = i;//根节点在中序遍历中的位置
            }
        }
        chang = wei - il; 
        TreeNode* root1 = new TreeNode(shu);//这个数作为根节点建立一棵树
        root1->left = dfs(preorder, inorder, pl + 1, pl + chang, il, wei - 1);
        root1->right = dfs(preorder, inorder, pl + chang + 1, pr, wei + 1, ir);
        return root1;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        length = preorder.size();
        return dfs(preorder, inorder, 0, length - 1, 0, length - 1);//后面的是用来记录当前的树是什么样子的,即边界
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值