leetcode 题库1028--从先序遍历还原二叉树

  1. 从先序遍历还原二叉树

我们从二叉树的根节点 root 开始进行深度优先搜索。

在遍历中的每个节点处,我们输出 D 条短划线(其中 D 是该节点的深度),然后输出该节点的值。(如果节点的深度为 D,则其直接子节点的深度为 D + 1。根节点的深度为 0)。

如果节点只有一个子节点,那么保证该子节点为左子节点。

给出遍历输出 S,还原树并返回其根节点 root。
思路:
因为给出的是先序遍历的二叉树,按照这个顺序重建二叉树,就需要将每个子树的根节点记录下来。
这里使用了一个栈来保存根节点的指针和深度。新节点加入二叉树中,需要从栈找到父节点,根据深度进行判断(深度相差1),就是一个单调栈,深度总是增加的。

TreeNode* recoverFromPreorder(string S) {
        //构造树,需要记录每层的节点,
        S+='-';                        //为了将最后一个数加入树中,不用多做处理
        TreeNode* root;
        int i = 0;
        int num = 0;
        while(i < S.size())
        {
            if(S[i]!='-')
            {
                num = num*10 + S[i]-'0';
            }
            else
            {
                break;
            }
            i++;
        }
        root = new TreeNode(num);

        bool flag = false;      //false  记录-,  true 记录数字
        int count = 0;          //记录长度-
        stack<pair<TreeNode*, int>> rec;
        rec.push(pair<TreeNode*,int>(root, 0));
        while(i < S.size())
        {
            if(flag)
            {
                if(S[i]=='-')
                {
                    flag = false;
                    //新节点
                    TreeNode* node = new TreeNode(num);
                    pair<TreeNode*, int> pre = rec.top();
                    while(pre.second+1!= count)
                    {
                        rec.pop();
                        pre = rec.top();
                    }
                    if(pre.second + 1 == count)
                    {
                        if(pre.first->left)
                        {
                            pre.first->right = node;
                            rec.push(pair<TreeNode*,int>(node, count));
                        }
                        else
                        {
                            pre.first->left = node;
                            rec.push(pair<TreeNode*,int>(node, count));
                        }
                    }
                    count=0;
                    i--;
                }
                else
                {
                    num = num*10 + S[i]-'0';
                }
            }
            else
            {
                if(S[i]!='-')
                {
                    flag = true;
                    num = 0;
                    i--;
                }
                else
                {
                    count++;
                }

            }
            i++;
        }

        return root;

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值