每日一算法题-重建二叉树

102 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情

一、题目

描述:
给定节点数为n的二叉树的前序遍历和中序遍历结果,请重建出该二叉树并返回它的头结点。

image.png

#include<iostream>
#include<vector>
using namespace std;

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    inline TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

TreeNode* makeTree(vector<int> pre,vector<int> vin) {
}

int main(int, char*[])
{
    vector<int> pre = {1, 2, 4, 7, 3, 5 ,6, 8};
    vector<int> vin = {4, 7, 2, 1, 5, 3, 8, 6};

    TreeNode* root = makeTree(pre, vin);

    cout << root->val << ' ';
    cout << root->left->val << ' ';
    cout << root->left->left->val << ' ';
    cout << root->left->left->right->val << ' ';
    cout << root->right->val << ' ';
    cout << root->right->left->val << ' ';
    cout << root->right->right->val << ' ';
    cout << root->right->right->left->val << endl;
    cout << "1 2 4 7 3 5 6 8" << endl;
}

二、分析

这道题考验对二叉树前序、中序、后序遍历的熟悉程度,实在比较陌生的话,就只能使用最原始最暴力的方法,找规律......
中序遍历的顺序是左根右,从这个顺序来看,从中序遍历的结果中找到根节点,左边的就肯定是左子树,右边的就肯定是右子树。
前序遍历的顺序是根左右,从这个顺序来看,可以很容易得到每个子树的根节点,配合中序遍历,就可以去中序遍历结果中去找到根节点,然后左边左子树,右边右子树这样进行子树的划分。
通过循环,不断的划分子树,直至为空。

三、模拟

  1. 1 -> 左:2,4,7 右:3,5,6,8
  2. 2 -> 左:4,7 右:空
  3. 4 -> 左:空 右:7
  4. 7 -> 左:空 右:空
  5. 3 -> 左:5 右:6,8
  6. 5 -> 左:空 右:空
  7. 6 -> 左:8 右:空
  8. 8 -> 左:空 右:空

四、实现

TreeNode* makeTreeDfs(vector<int>& pre,vector<int>& vin, int preStart, int preEnd, int vinStart, int vinEnd) {
    if(preStart > preEnd) return nullptr;
    TreeNode* root = new TreeNode(pre[preStart]);
    int cur = vinStart;
    while(root->val != vin[cur]) ++cur;
    cur -= vinStart;
    root->left = makeTreeDfs(pre, vin, preStart + 1, cur + preStart, vinStart, cur + vinStart - 1);
    root->right = makeTreeDfs(pre, vin, cur + preStart + 1, preEnd, cur + vinStart + 1, vinEnd);
    return root;
}

TreeNode* makeTree(vector<int> pre,vector<int> vin) {
    if(pre.empty()) return nullptr;
    return makeTreeDfs(pre, vin, 0, pre.size() - 1, 0, vin.size() - 1);
}

五、结言

掌握基础算法,遇事儿咱不慌。

创作不易,留个赞再走吧!如果对文章内容有任何指正,欢迎评论!