题解 | #重建二叉树#

重建二叉树

https://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6

思路:利用前序中序遍历的性质,首先在前序中找到根节点,那么在中序遍历中,根节点的左边一定是他的左子树,右边是右子树,然后根据这个特点,对左和右子树继续进行递归

TreeNode* reConBTree(vector<int> pre,int preleft,int preright,vector<int> vin,int vinleft,int vinright)
    {
        /*
        pre为前序序列,vin为中序序列
        preleft为前序序列左边界,preright为前序序列右边界
        vinleft为中序序列左边界,vinright为中序序列右边界
        */
        //如果左边界>右边界,说明没有子树了,返回空指针
        if(preleft > preright || vinleft > vinright)
        {
            return nullptr;
        }
        //前序序列的第一个元素必定为根节点
        int preroot = pre[preleft];
        int vinroot = vinleft;
        //找到根节点在中序序列中的位置
        while(vin[vinroot] != preroot)
            vinroot++;
        //构建根节点
        TreeNode* s = new TreeNode(preroot);
        //左子树的结点数目,即中序序列中根节点到左边界的距离
        int distance = vinroot-vinleft;
        //左子树的所有结点在前序序列中的位置[preleft+1,preleft+distance]
        //左子树的所有结点在中序序列中的位置[vinleft,vinroot-1]
        s->left = reConBTree(pre, preleft+1,preleft+distance, vin, vinleft, vinroot-1);
        //右子树的所有结点在前序序列中的位置[preleft+distance+1,preright]
        //右子树的所有结点在中序序列中的位置[vinroot+1,vinright]
        s->right = reConBTree(pre, preleft+distance+1, preright, vin, vinroot+1, vinright);
        return s;
    }
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        return reConBTree(pre, 0, pre.size()-1, vin, 0, vin.size());
    }
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        int n = pre.size();
        int m = vin.size();
        //如果为0,说明没有子树了
        if(n == 0 || m == 0)
            return nullptr;
        //构建根节点
        TreeNode *root = new TreeNode(pre[0]);
        for(int i = 0;i<vin.size();++i)
        {
            //找到中序遍历中的前序第一个元素
            if(pre[0] == vin[i])
            {
                //左子树的前序遍历序列
                vector<int> leftpre(pre.begin()+1,pre.begin()+i+1);
                //左子树的中序遍历序列
                vector<int> leftvin(vin.begin(),vin.begin()+i);
                //构建左子树
                root->left = reConstructBinaryTree(leftpre,leftvin);
                //右子树的前序遍历序列
                vector<int> rightpre(pre.begin()+i+1,pre.end());
                //右子树的中序遍历序列
                vector<int> rightvin(vin.begin()+i+1,vin.end());
                //构建右子树
                root->right = reConstructBinaryTree(rightpre,rightvin);
                break;
            }
        }
        return root;
    }

全部评论

相关推荐

01-03 19:22
宁夏大学 运营
点赞 评论 收藏
分享
时间线:&nbsp;1.4-1.5:&nbsp;boss&nbsp;牛客&nbsp;官网&nbsp;实习僧海投了两天,&nbsp;感觉确实没啥招人的啊,&nbsp;心里凉了一半.1.6:&nbsp;中午快手约面,&nbsp;下午字节hr飞书私聊约面,&nbsp;当时想着第一次面大厂感觉三个过一个一面就已经赢了.1.7:&nbsp;下午&nbsp;3点大厂处女面,&nbsp;哈哈面试官是重邮红岩的直接保送;&nbsp;5点快手一面,&nbsp;我说这个是我的第二次大厂面试,&nbsp;面试官问要是拿到字节和快手选择哪个,&nbsp;我说昨天看了一晚上快手百分百选快手哈哈哈.&nbsp;晚上5.30字节约二面,&nbsp;快手约二面,&nbsp;小红书约一面.1.8:&nbsp;下午2点快手二面,&nbsp;聊天面体验非常好(当天电话确认入职时间);&nbsp;4点字节二面这次不是校友了,&nbsp;然后有一个CSS实现switch效果的忘记属性咋写了,&nbsp;感觉危了;&nbsp;7.30&nbsp;问字节hr是不是挂了;&nbsp;9点开始小红书一面,&nbsp;难死我了,&nbsp;但我还是笑着面完了,&nbsp;然后卸载了小红书,&nbsp;但是过了一会会小红书hr约二面,&nbsp;遂下回来了字节约三面.1.9:&nbsp;下午2点字节三面,&nbsp;依旧聊天+算法,&nbsp;自己太菜了有一个写错了,&nbsp;面完感觉又危了;&nbsp;5点面小红书20min结束(offer审批);5.30又去问字节hr是不是挂了,&nbsp;hr小姐姐说干嘛用一个句式,&nbsp;我说手写题又又又没写出来😂,&nbsp;2min后约hr面;8.30&nbsp;快手offer总结,&nbsp;自己运气好遇到了好公司好部门好面试官,&nbsp;字节剪映&nbsp;快手电商&nbsp;小红书支付的面试体验都非常好,&nbsp;不会的题会带你一步一步思考,&nbsp;流程也非常快全部都是当天推进,&nbsp;小红书是以分钟为单位推进.&nbsp;&nbsp;面经以及细节等我慢慢整理,&nbsp;&nbsp;以及保佑所有的审批不要出问题,&nbsp;我是真怕最后全过了0offer😂bg:&nbsp;重邮&nbsp;大数据&nbsp;蓝山工作室&nbsp;一段非大厂实习
独角仙梦境:这是真👻了
找实习记录
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务