剑指 offer acwing 18 重建二叉树(DFS)

题面

在这里插入图片描述

题解

  1. 前置知识 :遍历方式是根据 根节点 的位置分类的 ,前序遍历(根左右)中序遍历(左根右) 后序遍历(左右根),对于树的层次遍历 ,就是按找BFS的方式遍历,在每个叶子节点后加一个NULL (如图中方式)
  1. 给定前序和中序,我们就可以dfs递归确定一颗树,就拿图中样例来看,首先前序(根左右),那么3肯定是根节点,那么看中序遍历的3所在位置,因为中序遍历是左根右,所以3之前的9是左子树 ,3之后的 15 20 7 是右子树
  1. 右子树的前序遍历第一个是20 ,那么20就是右子树的根节点,中序遍历中20 之前的15 就是20 的左子树 ,7就是 20 的右子树 ,同样左子树也一样
  1. 这样dfs递归就可以实现,但是边界问题要考虑清楚,就是递归的区间长度

代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
    
    
public:

    unordered_map<int, int> mp;

    TreeNode *dfs(vector<int> preorder, vector<int> inorder, int pl, int pr, int il, int ir) {
    
    

    if (pl > pr) return NULL;
    int k = mp[preorder[pl]];   //中序遍历的根节点下标
    TreeNode *root = new TreeNode(inorder[k]);
    root->left = dfs(preorder, inorder, pl + 1, pl + 1 + k - il - 1, il, il + k - 1);
    root->right = dfs(preorder, inorder, pl + 1 + k - il - 1 + 1, pr, k + 1, ir);
    return root;
    }
    
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
    
    
        
        int n = preorder.size();
        for (int i = 0; i < inorder.size(); i++) mp[inorder[i]] = i;
        return dfs(preorder, inorder, 0, n - 1, 0, n - 1);
        
    }
    
    
};

猜你喜欢

转载自blog.csdn.net/qq_44791484/article/details/114886811