堆栈迭代+DFS递归 1028. 从先序遍历还原二叉树

根据先序遍历结果,利用递归DFS和迭代堆栈方法重建二叉树。递归时,全局变量i记录当前位置,判断是否能作为左子树并递归构建子树。迭代中,栈内节点数表示当前深度,新节点赋给栈顶元素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

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

给出遍历输出 S,还原树并返回其根节点 root。

示例 1:

在这里插入图片描述

输入:"1-2--3--4-5--6--7"
输出:[1,2,5,3,4,6,7]

示例 2:

在这里插入图片描述

输入:"1-2--3---4-5--6---7"
输出:[1,2,5,3,null,6,null,4,null,7]

示例 3:

在这里插入图片描述

输入:"1-401--349---90--88"
输出:[1,401,null,349,88,90]

提示:

原始树中的节点数介于 11000 之间。
每个节点的值介于 110 ^ 9 之间。

递归+DFS

全局变量i记录当前遍历的位置;
(1)获取当前节点,若不能作为左子树,则还原i,返回上一层;
(2)若能做左子树,放入左子树位置;看后面是否有右子树,无则递归左子树的子树;
(3)若还有右子树,则左子树无子树,放入右子树后递归右子树的子树;

每次判断完都需要还原i;

/**
 * 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:
    TreeNode* recoverFromPreorder(string S) {
        if(!S.size()) return NULL;
        i=0;
        int num=cal(S);
        TreeNode * root = new TreeNode(num);
        buildtree(S,0,root);
        return root;
    }
private:
    int i;  //用于遍历字符串

    void buildtree(string S,int n,TreeNode * root){
        int cnt=0;
        int t=i;
        while(S[i]=='-'){i++; cnt++;}  //若写在while里面,非判断也会让i++
        if(cnt==n+1){      //若有左子节点
            int tmp=cal(S);
            root->left=new TreeNode(tmp);      //放入左边


            cnt=0;
            t=i;
            while(S[i]=='-') {i++;cnt++;}
            if(cnt==n+1){     //若有右子节点
                int tmp=cal(S);
                root->right=new TreeNode(tmp);  //放入右边
                buildtree(S,n+1,root->right);  //往后递归
            }else if (cnt>n+1){  //若无右子节点,但有节点
                i=t;
                buildtree(S,n+1,root->left);//往左边递归
                //左边建树完成
                cnt=0;
                t=i;
                while(S[i]=='-'){i++; cnt++;}  //检查右子树
                if(cnt==n+1){    //若有右子树
                    tmp=cal(S);
                    root->right=new TreeNode(tmp);
                    buildtree(S,n+1,root->right);  //进入右子树递归
                }else i=t;  //若无右子树
            }else i=t;
        }else i=t;
        return;
    }

    int cal(string S){
        int res=0;
        while(isdigit(S[i])){
            res=res*10+(S[i++]-'0');
        }
        return res;
    }
};

迭代+堆栈

关键点:
栈内节点数量为当前构造的深度;
每次得到新节点,赋给栈顶元素;

/**
 * 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:
    TreeNode* recoverFromPreorder(string S) {
        if(!S.size()) return NULL;    //确定S大小
        stack<TreeNode*> T;           //建立堆栈
        i=0;                          //从头开始遍历S
        int tmp=calnum(S);            //将根节点入栈
        TreeNode* root=new TreeNode(tmp);  
        T.push(root);                 
        while(i<S.size()){             //遍历S
            int len=calflr(S);        //计算当前节点深度
            int num=calnum(S);         //计算当前节点数值
            TreeNode * newnode=new TreeNode(num);   //构造当前节点
            while(len<T.size()) T.pop();   //若当前节点深度小于栈内节点数量,栈内节点出栈
            TreeNode * temp=T.top();       //取出栈顶元素
            if(!temp->left) temp->left=newnode;   //先判断栈顶元素有无左子树,无则赋值
            else temp->right=newnode;       //有则右子树赋值
            T.push(newnode);                //新节点入队
        }
        return root;
    }
private:
    int i;
    int calnum(string S){
        int res=0;
        while(isdigit(S[i]))    res=res*10+S[i++]-'0';
        return res;
    }

    int calflr(string S){
        int cnt=0;
        while(i<S.size()&&S[i]=='-') {i++;cnt++;}
        return cnt;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值