剑指offer 07:重建二叉树

思路:
1,首先这题是针对二叉树元素不重复的情况进行解决,那么就比较容易找到中序遍历中的根节点位置
2,提供二叉树的前序和中序遍历,就能够确定根结点,以及左右子树长度
3,首先,根节点就是前序遍历的第一个元素,然后再中序中搜索该元素,确定中序遍历中根结点位置;
确定中序遍历中根节点位置后,依据根节点序号-该子树最左端序号就能得到左子树长度(右子树就是该子树最右端序号-根结点序号)
4,题目要求构建树,因此要采用递归的方法将大的二叉树不断分解成小的二叉树,然后从小到大构建(从叶子结点开始)
5,解答时要注意一个问题,递归的子函数访问preorder(搜索根节点时用)和inorder(代码中用哈希表保存进行搜索),可以直接把变量地址作为函数变量,也可以赋给类的成员进行访问。

/**
 * 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> dic;
    

    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
    //this是一个指针,它时时刻刻指向你这个实例本身,此处对类中的preorder进行赋值
    this->preorder=preorder;    
    for(int i=0;i<inorder.size();i++)
        dic[inorder[i]]=i;

    return recursive(0,0,preorder.size()-1);
    }

private:
    vector<int> preorder;  //将所给的先序进行保存,方便成员函数访问  

    //前序的根节点,中序的左边界,中序的右边界
    TreeNode* recursive(int pre_root,int in_left,int in_right){
        if(in_left>in_right)
            return NULL;

        TreeNode* root = new TreeNode(preorder[pre_root]);
        int in_root=dic[preorder[pre_root]];  //找出中序中的根结点
        //左子树长度为in_root-in_left,左子树的根结点在前序中为pre_order+1,左子树在中序的范围为in_left到in_root-1
        //右子树长度没用到,右子树根结点在前序中为pre_order+左子树长度+1,右子树在中序的范围为in_root+1到in_right
        root->left=recursive(pre_root+1,in_left,in_root-1);
        root->right=recursive(pre_root+in_root-in_left+1,in_root+1,in_right);
        return root;
    }
};

你可能感兴趣的:(Leetcode刷题,c++)