当前位置 博文首页 > 中流击水,浪遏飞舟:dfs&&剑指 Offer 07. 重建二叉树

    中流击水,浪遏飞舟:dfs&&剑指 Offer 07. 重建二叉树

    作者:[db:作者] 时间:2021-08-26 12:40

    目的:给出前序遍历和中序遍历的结果,且不包含重复数字,求出原始二叉树。

    思路:二叉树前序遍历的第一个结点为根节点,依据中序遍历找到根节点,此时中序遍历根节点左边全部是左子树,右边全部是右子树。按照这么个递归分治,最终重建二叉树,不过二叉树的边界挺难看懂,想半天。。

    dfs:(1)递归参数;(2)递归终止条件;(3)递推工作。

    心得:太难了,看题解都得看半天,最后才差不多研究出那么一回事。

    注意:按照前序遍历理解传递的参数:根结点root,左子树的左边界left,右子树的右边界right。每次在根结点处建立新节点值,当left>right时返回。

    参考:
    面试题07. 重建二叉树(递归法,清晰图解)

    /**
     * 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> div;   //哈希表记录中序遍历的索引值,每次找到对应索引值,很快划分左右子树
        TreeNode* dfs(int root,int left,int right,vector<int>& preorder){     //参数:根,左子树的左边界,右子树的右边界,前序遍历数组
            if(left>right){
                return NULL;    //递归终止条件
            }
            int i=div[preorder[root]];      //找到中序遍历的根节点
            TreeNode*node=new TreeNode(preorder[root]);     //建立新根节点
            node->left=dfs(root+1,left,i-1,preorder);    //按前序遍历看左子树的root
            node->right=dfs((i-1-left)+root+1+1,i+1,right,preorder);     //按前序遍历看右子树的root
            return node;
        }
        TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
            for(int i=0;i<inorder.size();i++){
                div[inorder[i]]=i;
            }
            return dfs(0,0,inorder.size()-1,preorder);
        }
    };
    
    
    cs