【算法题】重建二叉树

重建二叉树

https://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6?tpId=196&tqId=37109&rp=1&sourceUrl=%2Fexam%2Foj%3FquestionJobId%3D10%26subTabName%3Donline_coding_page&difficulty=undefined&judgeStatus=undefined&tags=&title=

这题说的是根据前序遍历数组和中序遍历数组来重建二叉树。我们知道前序遍历数组的第一个元素一定是根节点,在中序遍历数组中,根节点前面的都是根节点左子树上的节点,根节点后面的都是根节点右子树上的节点。左右两棵子树我们可以使用递归的方式继续创建。

我们首先使用前序数组的第一个元素创建根节点,然后查询该节点在中序遍历数组中的位置,把中序数组分成两部分,一部分是根节点左子树的节点,一部分是根节点右子树的节点。为了方便查询,我们可以提前把中序数组存储到 map 中。


比如前序数组是:{1,2,4,7,3,5,6,8},中序数组是:{4,7,2,1,5,3,8,6}

那么 1 就是根节点,中序数组中 1 左边的 {4,7,2} 就是根节点左子树上的所有节点, 1 的右边 {5,3,8,6} 就是根节点右子树上的所有节点,如下图所示。

alt


    public TreeNode reConstructBinaryTree(int[] preOrder, int[] vinOrder) {
        // 为了方便后续进行查找,先把中序数组的所有值存储到map中
        Map<Integer, Integer> mp = new HashMap<>();
        int n = vinOrder.length;
        for (int i = 0; i < n; i++)
            mp.put(vinOrder[i], i);
        return build(preOrder, mp, 0, 0, n - 1);
    }

    /**
     * @param preorder 前序遍历的数组
     * @param mp       map,存储的是中序遍历的数组
     * @param preStart 前序遍历数组中的第一个元素下标
     * @param inStart  中序遍历数组的起始位置
     * @param inEnd    中序遍历数组的结束位置
     * @return
     */
    private TreeNode build(int[] preorder, Map<Integer, Integer> mp,
                           int preStart, int inStart, int inEnd) {
        if (inStart > inEnd)// 表示数组被访问完了。
            return null;
        // 使用前序数组的第一个元素创建node节点
        TreeNode node = new TreeNode(preorder[preStart]);
        // 查找node节点在中序数组中位置
        int index = mp.get(node.val);
        int leftCnt = index - inStart;// node节点左子树的所有节点个数。
        // 前序数组区间划分:
        // [preStart, preStart]根节点
        // [preStart + 1, preStart + leftCount]左子树
        // [preStart + leftCount + 1, ……]右子树
        // 中序数组区间划分:
        // [inStart, index - 1]左子树
        // [index, index]根节点
        // [index + 1, inEnd]右子树
        node.left = build(preorder, mp, preStart + 1, inStart, index - 1);// 递归创建左子树和右子树
        node.right = build(preorder, mp, preStart + leftCnt + 1, index + 1, inEnd);
        return node;
    }

public:
    TreeNode *reConstructBinaryTree(vector<int> &preOrder, vector<int> &vinOrder) {
        // 为了方便后续进行查找,先把中序数组的所有值存储到map中
        unordered_map<int, int> mp;
        int n = vinOrder.size();
        for (int i = 0; i < n; i++)
            mp[vinOrder[i]] = i;
        return build(preOrder, mp, 0, 0, n - 1);
    }

    /**
     * @param preorder 前序遍历的数组
     * @param mp       map,存储的是中序遍历的数组
     * @param preStart 前序遍历数组中的第一个元素下标
     * @param inStart  中序遍历数组的起始位置
     * @param inEnd    中序遍历数组的结束位置
     * @return
     */
    TreeNode *build(vector<int> &preorder, unordered_map<int, int> &mp,
                    int preStart, int inStart, int inEnd) {
        if (inStart > inEnd)// 表示数组被访问完了。
            return nullptr;
        // 使用前序数组的第一个元素创建node节点
        auto *node = new TreeNode(preorder[preStart]);
        // 查找node节点在中序数组中位置
        int index = mp[node->val];
        int leftCnt = index - inStart;// node节点左子树的所有节点个数。
        // 前序数组区间划分:
        // [preStart, preStart]根节点
        // [preStart + 1, preStart + leftCount]左子树
        // [preStart + leftCount + 1, ……]右子树
        // 中序数组区间划分:
        // [inStart, index - 1]左子树
        // [index, index]根节点
        // [index + 1, inEnd]右子树
        node->left = build(preorder, mp, preStart + 1, inStart, index - 1);// 递归创建左子树和右子树
        node->right = build(preorder, mp, preStart + leftCnt + 1, index + 1, inEnd);
        return node;
    }

各大厂算法面试题已经整理好了,请看这里:《算法专栏》

#笔试#

为了应对春招和秋招找工作,我经过长时间的收集和整理了各大厂的算法面试题,所有的算法题我都已经做了实现,大家可以根据自己需要面试的大厂选择练习即可。适宜人群: 在校生、社招求职者及自学者。

全部评论

相关推荐

02-24 10:34
门头沟学院 Java
已注销:之前发最美的女孩基本爱答不理,发最帅的hr终于有反馈了,女孩子也要自信起来
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务